From 0c3e70d62a3c1be1fdda079a3dab26be20d4f1ba Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 31 Oct 2022 17:08:10 +0100 Subject: [PATCH 01/93] use future resolution inside pm-pallet --- primitives/src/traits.rs | 2 +- primitives/src/traits/dispute_api.rs | 27 +++++++++++++ runtime/common/src/lib.rs | 1 + zrml/authorized/src/lib.rs | 42 ++++++++++++++++---- zrml/authorized/src/mock.rs | 33 +++++++++++++++- zrml/prediction-markets/src/lib.rs | 58 +++++++++++++++++----------- zrml/prediction-markets/src/mock.rs | 2 + zrml/simple-disputes/src/lib.rs | 28 ++++++++++++-- zrml/simple-disputes/src/mock.rs | 32 ++++++++++++++- 9 files changed, 186 insertions(+), 39 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..bbb9b789f 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -52,3 +52,30 @@ 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; + + fn add_auto_resolution( + market_id: &Self::MarketId, + future_block: Self::BlockNumber, + ) -> DispatchResult; + + fn remove_auto_resolution(market_id: &Self::MarketId, future_block: Self::BlockNumber); +} diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 7730e502c..21a01ff74 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/lib.rs b/zrml/authorized/src/lib.rs index dd09bad4f..1e838cd0e 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -42,10 +42,12 @@ mod pallet { PalletId, Twox64Concat, }; use frame_system::{ensure_signed, pallet_prelude::OriginFor}; - use sp_runtime::DispatchError; + use sp_runtime::{traits::Saturating, DispatchError}; use zeitgeist_primitives::{ - traits::DisputeApi, - types::{Market, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport}, + traits::{DisputeApi, DisputeResolutionApi}, + types::{ + Market, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport, Report, + }, }; use zrml_market_commons::MarketCommonsPalletApi; @@ -81,7 +83,16 @@ mod pallet { } else { return Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()); } - AuthorizedOutcomeReports::::insert(market_id, outcome); + if let Some(report) = AuthorizedOutcomeReports::::get(market_id) { + T::DisputeResolution::remove_auto_resolution(&market_id, report.at); + } + let now = frame_system::Pallet::::block_number(); + let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); + T::DisputeResolution::add_auto_resolution(&market_id, correction_period_ends_at)?; + + let report = Report { at: correction_period_ends_at, by: who.clone(), outcome }; + AuthorizedOutcomeReports::::insert(market_id, report); + Ok(()) } } @@ -91,6 +102,17 @@ mod pallet { /// Event type Event: From> + IsType<::Event>; + /// The period, in which the authority can correct the outcome of a market. + #[pallet::constant] + type CorrectionPeriod: Get; + + type DisputeResolution: DisputeResolutionApi< + AccountId = Self::AccountId, + BlockNumber = Self::BlockNumber, + MarketId = MarketIdOf, + Moment = MomentOf, + >; + /// Market commons type MarketCommons: MarketCommonsPalletApi< AccountId = Self::AccountId, @@ -159,17 +181,23 @@ mod pallet { if result.is_some() { AuthorizedOutcomeReports::::remove(market_id); } - Ok(result) + Ok(result.map(|report| report.outcome)) } } impl AuthorizedPalletApi for Pallet where T: Config {} + // TODO storage migration from OutcomeReport to Report /// Maps the market id to the outcome reported by the authorized account. #[pallet::storage] #[pallet::getter(fn outcomes)] - pub type AuthorizedOutcomeReports = - StorageMap<_, Twox64Concat, MarketIdOf, OutcomeReport, OptionQuery>; + pub type AuthorizedOutcomeReports = StorageMap< + _, + Twox64Concat, + MarketIdOf, + Report, + OptionQuery, + >; } #[cfg(any(feature = "runtime-benchmarks", test))] diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 8f4ceb01c..43ca89c71 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -18,15 +18,16 @@ #![cfg(test)] use crate::{self as zrml_authorized}; -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::{AuthorizedPalletId, BlockHashCount, MaxReserves, MinimumPeriod, BASE}, + traits::DisputeResolutionApi, types::{ - AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, MarketId, Moment, + AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketId, Moment, UncheckedExtrinsicTest, }, }; @@ -50,8 +51,36 @@ 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) + } + + fn add_auto_resolution( + market_id: &Self::MarketId, + future_block: Self::BlockNumber, + ) -> frame_support::pallet_prelude::DispatchResult { + Ok(()) + } + + fn remove_auto_resolution(market_id: &Self::MarketId, future_block: Self::BlockNumber) {} +} + impl crate::Config for Runtime { type Event = (); + type CorrectionPeriod = CorrectionPeriod; + 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 1fde44739..dffb17813 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, @@ -472,18 +472,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, @@ -2478,21 +2472,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] { @@ -2724,4 +2703,37 @@ 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) + } + + fn add_auto_resolution( + market_id: &Self::MarketId, + future_block: Self::BlockNumber, + ) -> DispatchResult { + >::try_mutate(future_block, |ids| { + ids.try_push(*market_id).map_err(|_| >::StorageOverflow) + })?; + Ok(()) + } + + fn remove_auto_resolution(market_id: &Self::MarketId, future_block: Self::BlockNumber) { + MarketIdsPerDisputeBlock::::mutate(future_block, |ids| { + remove_item::, _>(ids, market_id); + }); + } + } } diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 3cba85085..d9ea0d2a2 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -213,6 +213,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; @@ -260,6 +261,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..0aeb02b90 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -36,9 +36,9 @@ mod pallet { traits::{Currency, Get, Hooks, IsType}, PalletId, }; - use sp_runtime::DispatchError; + use sp_runtime::{traits::Saturating, DispatchError}; use zeitgeist_primitives::{ - traits::DisputeApi, + traits::{DisputeApi, DisputeResolutionApi}, types::{Market, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport}, }; use zrml_market_commons::MarketCommonsPalletApi; @@ -59,6 +59,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, @@ -99,13 +106,26 @@ 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()); } + if let Some(last_dispute) = disputes.last() { + let dispute_duration_ends_at_block = + last_dispute.at.saturating_add(market.deadlines.dispute_duration); + T::DisputeResolution::remove_auto_resolution( + market_id, + dispute_duration_ends_at_block, + ); + } + 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); + T::DisputeResolution::add_auto_resolution(market_id, dispute_duration_ends_at_block)?; Ok(()) } diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index 3553c5aa9..9e751d099 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,35 @@ 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) + } + + fn add_auto_resolution( + market_id: &Self::MarketId, + future_block: Self::BlockNumber, + ) -> frame_support::pallet_prelude::DispatchResult { + Ok(()) + } + + fn remove_auto_resolution(market_id: &Self::MarketId, future_block: Self::BlockNumber) {} +} + impl crate::Config for Runtime { type Event = (); + type DisputeResolution = NoopResolution; type MarketCommons = MarketCommons; type PalletId = SimpleDisputesPalletId; } From 7e77047faef7c5bbf494c054839ad903dcd1013e Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 1 Nov 2022 08:07:00 +0100 Subject: [PATCH 02/93] wip --- primitives/src/constants/mock.rs | 1 + primitives/src/market.rs | 6 +++ primitives/src/traits/dispute_api.rs | 15 ++++-- zrml/authorized/src/lib.rs | 70 +++++++++++++++++++--------- zrml/authorized/src/mock.rs | 12 +++-- zrml/court/src/lib.rs | 12 +++++ zrml/prediction-markets/src/lib.rs | 53 +++++++++++++-------- zrml/prediction-markets/src/mock.rs | 19 ++++---- zrml/simple-disputes/src/lib.rs | 46 ++++++++++++++---- zrml/simple-disputes/src/mock.rs | 16 +++---- 10 files changed, 176 insertions(+), 74 deletions(-) diff --git a/primitives/src/constants/mock.rs b/primitives/src/constants/mock.rs index 8b4bec96c..db4e3e1ce 100644 --- a/primitives/src/constants/mock.rs +++ b/primitives/src/constants/mock.rs @@ -11,6 +11,7 @@ use orml_traits::parameter_type_with_key; // Authorized parameter_types! { pub const AuthorizedPalletId: PalletId = PalletId(*b"zge/atzd"); + pub const CorrectionPeriod: BlockNumber = 2; } // Court diff --git a/primitives/src/market.rs b/primitives/src/market.rs index 5ea4b1d87..6e62e5f7b 100644 --- a/primitives/src/market.rs +++ b/primitives/src/market.rs @@ -215,6 +215,12 @@ pub struct Report { pub outcome: OutcomeReport, } +#[derive(Clone, Decode, Encode, Eq, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)] +pub struct AuthorityReport { + pub at: BlockNumber, + pub outcome: OutcomeReport, +} + /// Contains a market id and the market period. /// /// * `BN`: Block Number diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index bbb9b789f..cba90b597 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -51,6 +51,13 @@ pub trait DisputeApi { market_id: &Self::MarketId, market: &Market, ) -> Result, DispatchError>; + + // TODO doc comment + fn get_auto_resolve( + disputes: &[MarketDispute], + market_id: &Self::MarketId, + market: &Market, + ) -> Result, DispatchError>; } pub trait DisputeResolutionApi { @@ -72,10 +79,12 @@ pub trait DisputeResolutionApi { market: &Market, ) -> Result; - fn add_auto_resolution( + // TODO doc comment + fn add_auto_resolve( market_id: &Self::MarketId, - future_block: Self::BlockNumber, + resolution: Self::BlockNumber, ) -> DispatchResult; - fn remove_auto_resolution(market_id: &Self::MarketId, future_block: Self::BlockNumber); + // TODO doc comment + fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber); } diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 1e838cd0e..838a3502f 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -46,7 +46,8 @@ mod pallet { use zeitgeist_primitives::{ traits::{DisputeApi, DisputeResolutionApi}, types::{ - Market, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport, Report, + AuthorityReport, Market, MarketDispute, MarketDisputeMechanism, MarketStatus, + OutcomeReport, }, }; use zrml_market_commons::MarketCommonsPalletApi; @@ -83,14 +84,13 @@ mod pallet { } else { return Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()); } - if let Some(report) = AuthorizedOutcomeReports::::get(market_id) { - T::DisputeResolution::remove_auto_resolution(&market_id, report.at); - } + + Self::remove_auto_resolve(&market_id); let now = frame_system::Pallet::::block_number(); let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); - T::DisputeResolution::add_auto_resolution(&market_id, correction_period_ends_at)?; + T::DisputeResolution::add_auto_resolve(&market_id, correction_period_ends_at)?; - let report = Report { at: correction_period_ends_at, by: who.clone(), outcome }; + let report = AuthorityReport { at: correction_period_ends_at, outcome }; AuthorizedOutcomeReports::::insert(market_id, report); Ok(()) @@ -151,7 +151,20 @@ mod pallet { #[pallet::storage_version(STORAGE_VERSION)] pub struct Pallet(PhantomData); - impl Pallet where T: Config {} + impl Pallet + where + T: Config, + { + fn get_auto_resolve(market_id: &MarketIdOf) -> Option { + AuthorizedOutcomeReports::::get(market_id).map(|report| report.at) + } + + fn remove_auto_resolve(market_id: &MarketIdOf) { + Self::get_auto_resolve(market_id).map(|at| { + T::DisputeResolution::remove_auto_resolve(&market_id, at); + }); + } + } impl DisputeApi for Pallet where @@ -167,21 +180,41 @@ mod pallet { fn on_dispute( _: &[MarketDispute], _: &Self::MarketId, - _: &Market, + market: &Market, ) -> DispatchResult { - Ok(()) + if let MarketDisputeMechanism::Authorized(_) = market.dispute_mechanism { + Ok(()) + } else { + Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) + } } fn on_resolution( _: &[MarketDispute], market_id: &Self::MarketId, - _: &Market>, + market: &Market>, ) -> Result, DispatchError> { - let result = AuthorizedOutcomeReports::::get(market_id); - if result.is_some() { - AuthorizedOutcomeReports::::remove(market_id); + if let MarketDisputeMechanism::Authorized(_) = market.dispute_mechanism { + let result = AuthorizedOutcomeReports::::get(market_id); + if result.is_some() { + AuthorizedOutcomeReports::::remove(market_id); + } + Ok(result.map(|report| report.outcome)) + } else { + Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) + } + } + + fn get_auto_resolve( + _: &[MarketDispute], + market_id: &Self::MarketId, + market: &Market>, + ) -> Result, DispatchError> { + if let MarketDisputeMechanism::Authorized(_) = market.dispute_mechanism { + Ok(Self::get_auto_resolve(market_id)) + } else { + Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) } - Ok(result.map(|report| report.outcome)) } } @@ -191,13 +224,8 @@ mod pallet { /// Maps the market id to the outcome reported by the authorized account. #[pallet::storage] #[pallet::getter(fn outcomes)] - pub type AuthorizedOutcomeReports = StorageMap< - _, - Twox64Concat, - MarketIdOf, - Report, - OptionQuery, - >; + pub type AuthorizedOutcomeReports = + StorageMap<_, Twox64Concat, MarketIdOf, AuthorityReport, OptionQuery>; } #[cfg(any(feature = "runtime-benchmarks", test))] diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 43ca89c71..15889217a 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -24,7 +24,9 @@ use sp_runtime::{ traits::{BlakeTwo256, IdentityLookup}, }; use zeitgeist_primitives::{ - constants::mock::{AuthorizedPalletId, BlockHashCount, MaxReserves, MinimumPeriod, BASE}, + constants::mock::{ + AuthorizedPalletId, BlockHashCount, CorrectionPeriod, MaxReserves, MinimumPeriod, BASE, + }, traits::DisputeResolutionApi, types::{ AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketId, Moment, @@ -67,14 +69,14 @@ impl DisputeResolutionApi for NoopResolution { Ok(0) } - fn add_auto_resolution( - market_id: &Self::MarketId, - future_block: Self::BlockNumber, + fn add_auto_resolve( + _market_id: &Self::MarketId, + _resolution: Self::BlockNumber, ) -> frame_support::pallet_prelude::DispatchResult { Ok(()) } - fn remove_auto_resolution(market_id: &Self::MarketId, future_block: Self::BlockNumber) {} + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) {} } impl crate::Config for Runtime { diff --git a/zrml/court/src/lib.rs b/zrml/court/src/lib.rs index d727516c4..270e60f0a 100644 --- a/zrml/court/src/lib.rs +++ b/zrml/court/src/lib.rs @@ -546,6 +546,18 @@ mod pallet { RequestedJurors::::remove_prefix(market_id, None); Ok(Some(first)) } + + fn get_auto_resolve( + _: &[MarketDispute], + _: &Self::MarketId, + market: &Market>, + ) -> Result, DispatchError> { + if market.dispute_mechanism != MarketDisputeMechanism::Court { + return Err(Error::::MarketDoesNotHaveCourtMechanism.into()); + } + + Ok(None) + } } impl CourtPalletApi for Pallet where T: Config {} diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index dffb17813..85830e6fa 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -165,7 +165,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, disputes_len) = Self::clear_auto_resolve(&market_id, &market)?; T::MarketCommons::remove_market(&market_id)?; Disputes::::remove(market_id); @@ -275,7 +275,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, disputes_len) = Self::clear_auto_resolve(&market_id, &market)?; let market = T::MarketCommons::market(&market_id)?; let _ = Self::on_resolution(&market_id, &market)?; let weight = match market.market_type { @@ -1840,7 +1840,10 @@ 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, + market: &MarketOf, + ) -> Result<(u32, u32), DispatchError> { let market = T::MarketCommons::market(market_id)?; let (ids_len, disputes_len) = match market.status { MarketStatus::Reported => { @@ -1858,17 +1861,29 @@ 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) - }, - ) + let auto_resolve_block_opt = match market.dispute_mechanism { + MarketDisputeMechanism::Authorized(_) => { + T::Authorized::get_auto_resolve(&disputes, &market_id, &market)? + } + MarketDisputeMechanism::Court => { + T::Court::get_auto_resolve(&disputes, &market_id, &market)? + } + MarketDisputeMechanism::SimpleDisputes => { + T::SimpleDisputes::get_auto_resolve(&disputes, &market_id, &market)? + } + }; + if let Some(auto_resolve_block) = auto_resolve_block_opt { + MarketIdsPerDisputeBlock::::mutate( + auto_resolve_block, + |ids| -> (u32, u32) { + let ids_len = ids.len() as u32; + remove_item::, _>(ids, market_id); + (ids_len, disputes.len() as u32) + }, + ) + } else { + (0u32, disputes.len() as u32) + } } _ => (0u32, 0u32), }; @@ -2720,18 +2735,18 @@ mod pallet { Self::on_resolution(market_id, market) } - fn add_auto_resolution( + fn add_auto_resolve( market_id: &Self::MarketId, - future_block: Self::BlockNumber, + resolution: Self::BlockNumber, ) -> DispatchResult { - >::try_mutate(future_block, |ids| { + >::try_mutate(resolution, |ids| { ids.try_push(*market_id).map_err(|_| >::StorageOverflow) })?; Ok(()) } - fn remove_auto_resolution(market_id: &Self::MarketId, future_block: Self::BlockNumber) { - MarketIdsPerDisputeBlock::::mutate(future_block, |ids| { + fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber) { + MarketIdsPerDisputeBlock::::mutate(resolution, |ids| { remove_item::, _>(ids, market_id); }); } diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index d9ea0d2a2..8a3485d76 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -35,15 +35,15 @@ use sp_runtime::{ use substrate_fixed::{types::extra::U33, FixedI128, FixedU128}; use zeitgeist_primitives::{ constants::mock::{ - AuthorizedPalletId, BalanceFractionalDecimals, BlockHashCount, CourtCaseDuration, - CourtPalletId, DisputeFactor, ExistentialDeposit, ExistentialDeposits, ExitFee, - GetNativeCurrencyId, LiquidityMiningPalletId, MaxApprovals, MaxAssets, MaxCategories, - MaxDisputeDuration, MaxDisputes, MaxEditReasonLen, MaxGracePeriod, MaxInRatio, - MaxMarketPeriod, MaxOracleDuration, MaxOutRatio, MaxRejectReasonLen, MaxReserves, - MaxSubsidyPeriod, MaxSwapFee, MaxTotalWeight, MaxWeight, MinAssets, MinCategories, - MinDisputeDuration, MinLiquidity, MinOracleDuration, MinSubsidy, MinSubsidyPeriod, - MinWeight, MinimumPeriod, PmPalletId, SimpleDisputesPalletId, StakeWeight, SwapsPalletId, - TreasuryPalletId, BASE, CENT, MILLISECS_PER_BLOCK, + AuthorizedPalletId, BalanceFractionalDecimals, BlockHashCount, CorrectionPeriod, + CourtCaseDuration, CourtPalletId, DisputeFactor, ExistentialDeposit, ExistentialDeposits, + ExitFee, GetNativeCurrencyId, LiquidityMiningPalletId, MaxApprovals, MaxAssets, + MaxCategories, MaxDisputeDuration, MaxDisputes, MaxEditReasonLen, MaxGracePeriod, + MaxInRatio, MaxMarketPeriod, MaxOracleDuration, MaxOutRatio, MaxRejectReasonLen, + MaxReserves, MaxSubsidyPeriod, MaxSwapFee, MaxTotalWeight, MaxWeight, MinAssets, + MinCategories, MinDisputeDuration, MinLiquidity, MinOracleDuration, MinSubsidy, + MinSubsidyPeriod, MinWeight, MinimumPeriod, PmPalletId, SimpleDisputesPalletId, + StakeWeight, SwapsPalletId, TreasuryPalletId, BASE, CENT, MILLISECS_PER_BLOCK, }, types::{ AccountIdTest, Amount, Asset, Balance, BasicCurrencyAdapter, BlockNumber, BlockTest, @@ -212,6 +212,7 @@ impl pallet_timestamp::Config for Runtime { } impl zrml_authorized::Config for Runtime { + type CorrectionPeriod = CorrectionPeriod; type Event = Event; type DisputeResolution = prediction_markets::Pallet; type MarketCommons = MarketCommons; diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index 0aeb02b90..454a8863e 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -94,6 +94,30 @@ mod pallet { #[pallet::hooks] impl Hooks for Pallet {} + impl Pallet + where + T: Config, + { + fn get_auto_resolve( + disputes: &[MarketDispute], + market: &Market>, + ) -> Option { + disputes.last().map(|last_dispute| { + last_dispute.at.saturating_add(market.deadlines.dispute_duration) + }) + } + + fn remove_auto_resolve( + disputes: &[MarketDispute], + market_id: &MarketIdOf, + market: &Market>, + ) { + Self::get_auto_resolve(disputes, market).map(|dispute_duration_ends_at_block| { + T::DisputeResolution::remove_auto_resolve(market_id, dispute_duration_ends_at_block) + }); + } + } + impl DisputeApi for Pallet where T: Config, @@ -113,19 +137,12 @@ mod pallet { if market.dispute_mechanism != MarketDisputeMechanism::SimpleDisputes { return Err(Error::::MarketDoesNotHaveSimpleDisputesMechanism.into()); } - if let Some(last_dispute) = disputes.last() { - let dispute_duration_ends_at_block = - last_dispute.at.saturating_add(market.deadlines.dispute_duration); - T::DisputeResolution::remove_auto_resolution( - market_id, - dispute_duration_ends_at_block, - ); - } + Self::remove_auto_resolve(disputes, market_id, market); 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); - T::DisputeResolution::add_auto_resolution(market_id, dispute_duration_ends_at_block)?; + T::DisputeResolution::add_auto_resolve(market_id, dispute_duration_ends_at_block)?; Ok(()) } @@ -146,6 +163,17 @@ mod pallet { Err(Error::::InvalidMarketStatus.into()) } } + + fn get_auto_resolve( + disputes: &[MarketDispute], + _: &Self::MarketId, + market: &Market>, + ) -> Result, DispatchError> { + if market.dispute_mechanism != MarketDisputeMechanism::SimpleDisputes { + return Err(Error::::MarketDoesNotHaveSimpleDisputesMechanism.into()); + } + Ok(Self::get_auto_resolve(disputes, market)) + } } impl SimpleDisputesPalletApi for Pallet where T: Config {} diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index 9e751d099..c1ed8d540 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -63,14 +63,14 @@ impl DisputeResolutionApi for NoopResolution { Ok(0) } - fn add_auto_resolution( - market_id: &Self::MarketId, - future_block: Self::BlockNumber, - ) -> frame_support::pallet_prelude::DispatchResult { - Ok(()) - } - - fn remove_auto_resolution(market_id: &Self::MarketId, future_block: Self::BlockNumber) {} + fn add_auto_resolve( + _market_id: &Self::MarketId, + _resolution: Self::BlockNumber, + ) -> frame_support::pallet_prelude::DispatchResult { + Ok(()) + } + + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) {} } impl crate::Config for Runtime { From b16eb035bc1669556b52a65ed8b34dc00c2d97a7 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 1 Nov 2022 08:43:18 +0100 Subject: [PATCH 03/93] wip --- zrml/authorized/src/lib.rs | 2 +- zrml/authorized/src/tests.rs | 15 +++++++++---- zrml/court/src/lib.rs | 9 +++++++- zrml/court/src/mock.rs | 34 +++++++++++++++++++++++++++-- zrml/prediction-markets/src/lib.rs | 2 ++ zrml/prediction-markets/src/mock.rs | 1 + 6 files changed, 55 insertions(+), 8 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 838a3502f..746f14575 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -220,7 +220,7 @@ mod pallet { impl AuthorizedPalletApi for Pallet where T: Config {} - // TODO storage migration from OutcomeReport to Report + // TODO storage migration from OutcomeReport to AuthorityReport /// Maps the market id to the outcome reported by the authorized account. #[pallet::storage] #[pallet::getter(fn outcomes)] diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index 86351f465..bdfa94f7d 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -25,7 +25,7 @@ use crate::{ use frame_support::{assert_noop, assert_ok}; use zeitgeist_primitives::{ traits::DisputeApi, - types::{MarketDisputeMechanism, MarketStatus, OutcomeReport}, + types::{AuthorityReport, MarketDisputeMechanism, MarketStatus, OutcomeReport}, }; use zrml_market_commons::Markets; @@ -38,7 +38,12 @@ fn authorize_market_outcome_inserts_a_new_outcome() { 0, OutcomeReport::Scalar(1) )); - assert_eq!(AuthorizedOutcomeReports::::get(0).unwrap(), OutcomeReport::Scalar(1)); + let now = frame_system::Pallet::::block_number(); + let resolve_at = now + ::CorrectionPeriod::get(); + assert_eq!( + AuthorizedOutcomeReports::::get(0).unwrap(), + AuthorityReport { outcome: OutcomeReport::Scalar(1), at: resolve_at } + ); }); } @@ -182,13 +187,15 @@ fn authorize_market_outcome_allows_using_same_account_on_multiple_markets() { 1, OutcomeReport::Scalar(456) )); + let now = frame_system::Pallet::::block_number(); + let resolve_at = now + ::CorrectionPeriod::get(); assert_eq!( AuthorizedOutcomeReports::::get(0).unwrap(), - OutcomeReport::Scalar(123) + AuthorityReport { outcome: OutcomeReport::Scalar(123), at: resolve_at } ); assert_eq!( AuthorizedOutcomeReports::::get(1).unwrap(), - OutcomeReport::Scalar(456) + AuthorityReport { outcome: OutcomeReport::Scalar(456), at: resolve_at } ); }); } diff --git a/zrml/court/src/lib.rs b/zrml/court/src/lib.rs index 270e60f0a..a24766ab8 100644 --- a/zrml/court/src/lib.rs +++ b/zrml/court/src/lib.rs @@ -64,7 +64,7 @@ mod pallet { ArithmeticError, DispatchError, SaturatedConversion, }; use zeitgeist_primitives::{ - traits::DisputeApi, + traits::{DisputeApi, DisputeResolutionApi}, types::{Market, MarketDispute, MarketDisputeMechanism, OutcomeReport}, }; use zrml_market_commons::MarketCommonsPalletApi; @@ -144,6 +144,13 @@ mod pallet { #[pallet::constant] type CourtCaseDuration: Get; + type DisputeResolution: DisputeResolutionApi< + AccountId = Self::AccountId, + BlockNumber = Self::BlockNumber, + MarketId = MarketIdOf, + Moment = MomentOf, + >; + /// Event type Event: From> + IsType<::Event>; diff --git a/zrml/court/src/mock.rs b/zrml/court/src/mock.rs index 7d2c76934..c4757cfce 100644 --- a/zrml/court/src/mock.rs +++ b/zrml/court/src/mock.rs @@ -18,7 +18,9 @@ #![cfg(test)] use crate::{self as zrml_court}; -use frame_support::{construct_runtime, parameter_types, traits::Everything, PalletId}; +use frame_support::{ + construct_runtime, pallet_prelude::DispatchError, parameter_types, traits::Everything, PalletId, +}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, @@ -28,8 +30,9 @@ use zeitgeist_primitives::{ BlockHashCount, CourtCaseDuration, CourtPalletId, MaxReserves, MinimumPeriod, StakeWeight, BASE, }, + traits::DisputeResolutionApi, types::{ - AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, MarketId, Moment, + AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketId, Moment, UncheckedExtrinsicTest, }, }; @@ -59,8 +62,35 @@ 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) + } + + fn add_auto_resolve( + _market_id: &Self::MarketId, + _resolution: Self::BlockNumber, + ) -> frame_support::pallet_prelude::DispatchResult { + Ok(()) + } + + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) {} +} + impl crate::Config for Runtime { type CourtCaseDuration = CourtCaseDuration; + type DisputeResolution = NoopResolution; type Event = (); type MarketCommons = MarketCommons; type PalletId = CourtPalletId; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 85830e6fa..e8ab4c872 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -1694,6 +1694,8 @@ mod pallet { #[pallet::storage] pub type LastTimeFrame = StorageValue<_, TimeFrame>; + // TODO storage migration: delete Court and Authorized markets from here, + // TODO simple disputes is okay as it is /// A mapping of market identifiers to the block they were disputed at. /// A market only ends up here if it was disputed. #[pallet::storage] diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 8a3485d76..68f78bc43 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -222,6 +222,7 @@ impl zrml_authorized::Config for Runtime { impl zrml_court::Config for Runtime { type CourtCaseDuration = CourtCaseDuration; + type DisputeResolution = prediction_markets::Pallet; type Event = Event; type MarketCommons = MarketCommons; type PalletId = CourtPalletId; From d20682d8ce51c2d0249713e2a69aed61efdf63a2 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 1 Nov 2022 10:58:26 +0100 Subject: [PATCH 04/93] prepare storage migration --- primitives/src/market.rs | 2 +- zrml/authorized/src/lib.rs | 15 +++-- zrml/authorized/src/tests.rs | 6 +- zrml/prediction-markets/src/migrations.rs | 74 ++++++++++++++++++++++- zrml/prediction-markets/src/tests.rs | 34 +++++++++++ 5 files changed, 119 insertions(+), 12 deletions(-) diff --git a/primitives/src/market.rs b/primitives/src/market.rs index 6e62e5f7b..5eea2e465 100644 --- a/primitives/src/market.rs +++ b/primitives/src/market.rs @@ -217,7 +217,7 @@ pub struct Report { #[derive(Clone, Decode, Encode, Eq, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)] pub struct AuthorityReport { - pub at: BlockNumber, + pub resolve_at: Option, pub outcome: OutcomeReport, } diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 746f14575..593642c35 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -90,7 +90,7 @@ mod pallet { let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); T::DisputeResolution::add_auto_resolve(&market_id, correction_period_ends_at)?; - let report = AuthorityReport { at: correction_period_ends_at, outcome }; + let report = AuthorityReport { resolve_at: Some(correction_period_ends_at), outcome }; AuthorizedOutcomeReports::::insert(market_id, report); Ok(()) @@ -137,6 +137,8 @@ mod pallet { MarketIsNotDisputed, /// The report does not match the market's type. OutcomeMismatch, + /// The authority already made its report. + AuthorityAlreadyReported, } #[pallet::event] @@ -156,12 +158,12 @@ mod pallet { T: Config, { fn get_auto_resolve(market_id: &MarketIdOf) -> Option { - AuthorizedOutcomeReports::::get(market_id).map(|report| report.at) + AuthorizedOutcomeReports::::get(market_id).map(|report| report.resolve_at).flatten() } fn remove_auto_resolve(market_id: &MarketIdOf) { - Self::get_auto_resolve(market_id).map(|at| { - T::DisputeResolution::remove_auto_resolve(&market_id, at); + Self::get_auto_resolve(market_id).map(|resolve_at| { + T::DisputeResolution::remove_auto_resolve(&market_id, resolve_at); }); } } @@ -179,10 +181,13 @@ mod pallet { fn on_dispute( _: &[MarketDispute], - _: &Self::MarketId, + market_id: &Self::MarketId, market: &Market, ) -> DispatchResult { if let MarketDisputeMechanism::Authorized(_) = market.dispute_mechanism { + if AuthorizedOutcomeReports::::get(market_id).is_some() { + return Err(Error::::AuthorityAlreadyReported.into()); + } Ok(()) } else { Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index bdfa94f7d..a7335b7a3 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -42,7 +42,7 @@ fn authorize_market_outcome_inserts_a_new_outcome() { let resolve_at = now + ::CorrectionPeriod::get(); assert_eq!( AuthorizedOutcomeReports::::get(0).unwrap(), - AuthorityReport { outcome: OutcomeReport::Scalar(1), at: resolve_at } + AuthorityReport { outcome: OutcomeReport::Scalar(1), resolve_at } ); }); } @@ -191,11 +191,11 @@ fn authorize_market_outcome_allows_using_same_account_on_multiple_markets() { let resolve_at = now + ::CorrectionPeriod::get(); assert_eq!( AuthorizedOutcomeReports::::get(0).unwrap(), - AuthorityReport { outcome: OutcomeReport::Scalar(123), at: resolve_at } + AuthorityReport { outcome: OutcomeReport::Scalar(123), resolve_at } ); assert_eq!( AuthorizedOutcomeReports::::get(1).unwrap(), - AuthorityReport { outcome: OutcomeReport::Scalar(456), at: resolve_at } + AuthorityReport { outcome: OutcomeReport::Scalar(456), resolve_at } ); }); } diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index c4cc57292..6508afe89 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -24,15 +24,83 @@ use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, BoundedVec, }; +use frame_support::migration::storage_iter; +use frame_support::migration::put_storage_value; use parity_scale_codec::EncodeLike; use zeitgeist_primitives::{ constants::BASE, types::{MarketType, OutcomeReport}, }; +use zeitgeist_primitives::types::AuthorityReport; use zrml_authorized::{AuthorizedOutcomeReports, Pallet as AuthorizedPallet}; use zrml_court::{Pallet as CourtPallet, Votes}; use zrml_market_commons::{MarketCommonsPalletApi, Pallet as MarketCommonsPallet}; +const AUTHORIZED: &[u8] = b"Authorized"; +const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; + +pub struct AddFieldToAuthorityReport(PhantomData); + +// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. +impl + OnRuntimeUpgrade for AddFieldToAuthorityReport +where + ::MarketId: EncodeLike< + <::MarketCommons as MarketCommonsPalletApi>::MarketId, + > +{ + fn on_runtime_upgrade() -> Weight + where + T: Config, + { + let mut total_weight = T::DbWeight::get().reads(1); + let authorized_version = StorageVersion::get::>(); + if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION + { + log::info!( + "AddFieldToAuthorityReport: authorized version is {:?}, require {:?}; + authorized_version, + AUTHORIZED_REQUIRED_STORAGE_VERSION, + ); + return total_weight; + } + log::info!("AddFieldToAuthorityReport: Starting..."); + + for (key, value) in storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { + if let Some(old_value) = value { + let resolve_at: Option = None; + let new_value = AuthorityReport { resolve_at, outcome: old_value }; + put_storage_value::>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &key, + Some(new_value), + ); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + } + + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + } + + StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::info!("AddFieldToAuthorityReport: Done!"); + total_weight + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + Ok(()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + Ok(()) + } +} + +// TODO: Storage Migration: Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` + const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 1; const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 2; const COURT_REQUIRED_STORAGE_VERSION: u16 = 1; @@ -133,9 +201,9 @@ where let authorized_report = match AuthorizedOutcomeReports::::get(market_id) { Some(mut outcome_report) => { - if let OutcomeReport::Scalar(value) = outcome_report { - outcome_report = OutcomeReport::Scalar(to_fixed_point(value)); - }; + if let OutcomeReport::Scalar(value) = outcome_report.outcome { + outcome_report.outcome = OutcomeReport::Scalar(to_fixed_point(value)); + } Some(outcome_report) } None => None, diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index bd094ffbc..4e2de8bdc 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -41,6 +41,7 @@ use zeitgeist_primitives::{ ScalarPosition, ScoringRule, }, }; +use zrml_authorized::Error as AuthorizedError; use zrml_market_commons::MarketCommonsPalletApi; use zrml_swaps::Pools; @@ -2014,6 +2015,39 @@ fn it_allows_to_dispute_the_outcome_of_a_market() { }); } +#[test] +fn dispute_fails_authority_reported_already() { + ExtBuilder::default().build().execute_with(|| { + let end = 2; + simple_create_categorical_market(MarketCreation::Permissionless, 0..end, ScoringRule::CPMM); + + // Run to the end of the trading phase. + let market = MarketCommons::market(&0).unwrap(); + let grace_period = end + market.deadlines.grace_period; + run_to_block(grace_period + 1); + + assert_ok!(PredictionMarkets::report( + Origin::signed(BOB), + 0, + OutcomeReport::Categorical(1) + )); + + let dispute_at = grace_period + 2; + run_to_block(dispute_at); + + assert_ok!(Authorized::authorize_market_outcome( + Origin::signed(FRED), + 0, + OutcomeReport::Categorical(0) + )); + + assert_noop!( + PredictionMarkets::dispute(Origin::signed(CHARLIE), 1, OutcomeReport::Categorical(0)), + AuthorizedError::::AuthorityAlreadyReported + ); + }); +} + #[test] fn it_allows_anyone_to_report_an_unreported_market() { ExtBuilder::default().build().execute_with(|| { From 999a2fccdf309eed05086a6329da889b992e5457 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 1 Nov 2022 11:36:41 +0100 Subject: [PATCH 05/93] add UpdateMarketIdsPerDisputeBlock migration --- zrml/prediction-markets/src/migrations.rs | 111 +++++++++++++++++----- 1 file changed, 89 insertions(+), 22 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 6508afe89..86b180c12 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -15,23 +15,21 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{Config, Disputes, Pallet}; +use crate::{CacheSize, Config, Disputes, MarketIdOf, Pallet}; use alloc::{vec, vec::Vec}; use frame_support::{ dispatch::Weight, log, + migration::{put_storage_value, storage_iter}, pallet_prelude::PhantomData, traits::{Get, OnRuntimeUpgrade, StorageVersion}, BoundedVec, }; -use frame_support::migration::storage_iter; -use frame_support::migration::put_storage_value; use parity_scale_codec::EncodeLike; use zeitgeist_primitives::{ constants::BASE, - types::{MarketType, OutcomeReport}, + types::{AuthorityReport, MarketDisputeMechanism, MarketType, OutcomeReport}, }; -use zeitgeist_primitives::types::AuthorityReport; use zrml_authorized::{AuthorizedOutcomeReports, Pallet as AuthorizedPallet}; use zrml_court::{Pallet as CourtPallet, Votes}; use zrml_market_commons::{MarketCommonsPalletApi, Pallet as MarketCommonsPallet}; @@ -39,15 +37,27 @@ use zrml_market_commons::{MarketCommonsPalletApi, Pallet as MarketCommonsPallet} const AUTHORIZED: &[u8] = b"Authorized"; const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; +const PREDICTION_MARKETS: &[u8] = b"PredictionMarkets"; +const MARKET_IDS_PER_DISPUTE_BLOCK: &[u8] = b"MarketIdsPerDisputeBlock"; + +const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 1; +const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 2; +const COURT_REQUIRED_STORAGE_VERSION: u16 = 1; +const COURT_NEXT_STORAGE_VERSION: u16 = 2; +const MARKET_COMMONS_REQUIRED_STORAGE_VERSION: u16 = 2; +const MARKET_COMMONS_NEXT_STORAGE_VERSION: u16 = 3; +const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 5; +const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 6; + pub struct AddFieldToAuthorityReport(PhantomData); -// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. -impl - OnRuntimeUpgrade for AddFieldToAuthorityReport +// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. +impl OnRuntimeUpgrade + for AddFieldToAuthorityReport where ::MarketId: EncodeLike< <::MarketCommons as MarketCommonsPalletApi>::MarketId, - > + >, { fn on_runtime_upgrade() -> Weight where @@ -55,10 +65,9 @@ where { let mut total_weight = T::DbWeight::get().reads(1); let authorized_version = StorageVersion::get::>(); - if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION - { + if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION { log::info!( - "AddFieldToAuthorityReport: authorized version is {:?}, require {:?}; + "AddFieldToAuthorityReport: authorized version is {:?}, require {:?};", authorized_version, AUTHORIZED_REQUIRED_STORAGE_VERSION, ); @@ -66,7 +75,9 @@ where } log::info!("AddFieldToAuthorityReport: Starting..."); - for (key, value) in storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { + for (key, value) in + storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) + { if let Some(old_value) = value { let resolve_at: Option = None; let new_value = AuthorityReport { resolve_at, outcome: old_value }; @@ -99,16 +110,72 @@ where } } -// TODO: Storage Migration: Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` +pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); -const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 1; -const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 2; -const COURT_REQUIRED_STORAGE_VERSION: u16 = 1; -const COURT_NEXT_STORAGE_VERSION: u16 = 2; -const MARKET_COMMONS_REQUIRED_STORAGE_VERSION: u16 = 2; -const MARKET_COMMONS_NEXT_STORAGE_VERSION: u16 = 3; -const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 5; -const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 6; +// Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` +impl OnRuntimeUpgrade for UpdateMarketIdsPerDisputeBlock +where + ::MarketId: + EncodeLike<<::MarketCommons as MarketCommonsPalletApi>::MarketId>, +{ + fn on_runtime_upgrade() -> Weight + where + T: Config, + { + let mut total_weight = T::DbWeight::get().reads(1); + let prediction_markets_version = StorageVersion::get::>(); + if prediction_markets_version != PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION { + log::info!( + "prediction-markets version is {:?}, require {:?}", + prediction_markets_version, + PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION, + ); + return total_weight; + } + log::info!("UpdateMarketIdsPerDisputeBlock: Starting..."); + + for (key, mut bounded_vec) in storage_iter::< + BoundedVec<::MarketId, CacheSize>, + >(PREDICTION_MARKETS, MARKET_IDS_PER_DISPUTE_BLOCK) + { + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + + bounded_vec.retain(|id| { + if let Ok(market) = MarketCommonsPallet::::market(id) { + match market.dispute_mechanism { + MarketDisputeMechanism::Authorized(_) => false, + MarketDisputeMechanism::Court => false, + MarketDisputeMechanism::SimpleDisputes => true, + } + } else { + false + } + }); + put_storage_value::::MarketId, CacheSize>>( + PREDICTION_MARKETS, + MARKET_IDS_PER_DISPUTE_BLOCK, + &key, + bounded_vec, + ); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + } + + StorageVersion::new(PREDICTION_MARKETS_NEXT_STORAGE_VERSION).put::>(); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::info!("UpdateMarketIdsPerDisputeBlock: Done!"); + total_weight + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + Ok(()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + Ok(()) + } +} pub struct TransformScalarMarketsToFixedPoint(PhantomData); From 2d69ad2eb48d53ec16c6dc7e1b57bf24de91a8e6 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 1 Nov 2022 12:41:28 +0100 Subject: [PATCH 06/93] wip --- primitives/src/constants/mock.rs | 2 +- runtime/battery-station/src/parameters.rs | 1 + runtime/common/src/lib.rs | 5 +- runtime/zeitgeist/src/parameters.rs | 1 + zrml/authorized/src/tests.rs | 4 +- zrml/prediction-markets/src/lib.rs | 9 ++-- zrml/prediction-markets/src/migrations.rs | 12 +++-- zrml/prediction-markets/src/tests.rs | 56 +++++++++++++++-------- 8 files changed, 55 insertions(+), 35 deletions(-) diff --git a/primitives/src/constants/mock.rs b/primitives/src/constants/mock.rs index db4e3e1ce..d3d8c44ca 100644 --- a/primitives/src/constants/mock.rs +++ b/primitives/src/constants/mock.rs @@ -11,7 +11,7 @@ use orml_traits::parameter_type_with_key; // Authorized parameter_types! { pub const AuthorizedPalletId: PalletId = PalletId(*b"zge/atzd"); - pub const CorrectionPeriod: BlockNumber = 2; + pub const CorrectionPeriod: BlockNumber = 4; } // Court diff --git a/runtime/battery-station/src/parameters.rs b/runtime/battery-station/src/parameters.rs index 7db1eca0b..ab638fb30 100644 --- a/runtime/battery-station/src/parameters.rs +++ b/runtime/battery-station/src/parameters.rs @@ -48,6 +48,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; + pub const CorrectionPeriod: BlockNumber = 3 * BLOCKS_PER_HOUR; // Authority pub const MaxAuthorities: u32 = 32; diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 21a01ff74..b3499ea20 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -864,8 +864,9 @@ macro_rules! impl_config_traits { impl parachain_info::Config for Runtime {} impl zrml_authorized::Config for Runtime { - type Event = Event; + type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = zrml_prediction_markets::Pallet; + type Event = Event; type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; type WeightInfo = zrml_authorized::weights::WeightInfo; @@ -873,6 +874,7 @@ macro_rules! impl_config_traits { impl zrml_court::Config for Runtime { type CourtCaseDuration = CourtCaseDuration; + type DisputeResolution = zrml_prediction_markets::Pallet; type Event = Event; type MarketCommons = MarketCommons; type PalletId = CourtPalletId; @@ -983,6 +985,7 @@ macro_rules! impl_config_traits { } impl zrml_simple_disputes::Config for Runtime { + type DisputeResolution = zrml_prediction_markets::Pallet; type Event = Event; type MarketCommons = MarketCommons; type PalletId = SimpleDisputesPalletId; diff --git a/runtime/zeitgeist/src/parameters.rs b/runtime/zeitgeist/src/parameters.rs index 5b0978fb2..a3d460374 100644 --- a/runtime/zeitgeist/src/parameters.rs +++ b/runtime/zeitgeist/src/parameters.rs @@ -48,6 +48,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; + pub const CorrectionPeriod: BlockNumber = 6 * BLOCKS_PER_HOUR; // Authority pub const MaxAuthorities: u32 = 32; diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index a7335b7a3..d3ee7b421 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -39,7 +39,7 @@ fn authorize_market_outcome_inserts_a_new_outcome() { OutcomeReport::Scalar(1) )); let now = frame_system::Pallet::::block_number(); - let resolve_at = now + ::CorrectionPeriod::get(); + let resolve_at = Some(now + ::CorrectionPeriod::get()); assert_eq!( AuthorizedOutcomeReports::::get(0).unwrap(), AuthorityReport { outcome: OutcomeReport::Scalar(1), resolve_at } @@ -188,7 +188,7 @@ fn authorize_market_outcome_allows_using_same_account_on_multiple_markets() { OutcomeReport::Scalar(456) )); let now = frame_system::Pallet::::block_number(); - let resolve_at = now + ::CorrectionPeriod::get(); + let resolve_at = Some(now + ::CorrectionPeriod::get()); assert_eq!( AuthorizedOutcomeReports::::get(0).unwrap(), AuthorityReport { outcome: OutcomeReport::Scalar(123), resolve_at } diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index e8ab4c872..5633a420c 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -165,7 +165,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, &market)?; + let (ids_len, disputes_len) = Self::clear_auto_resolve(&market_id)?; T::MarketCommons::remove_market(&market_id)?; Disputes::::remove(market_id); @@ -275,7 +275,7 @@ mod pallet { market.status == MarketStatus::Reported || market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus, ); - let (ids_len, disputes_len) = Self::clear_auto_resolve(&market_id, &market)?; + let (ids_len, disputes_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 { @@ -1842,10 +1842,7 @@ mod pallet { } /// Clears this market from being stored for automatic resolution. - fn clear_auto_resolve( - market_id: &MarketIdOf, - market: &MarketOf, - ) -> Result<(u32, u32), DispatchError> { + fn clear_auto_resolve(market_id: &MarketIdOf) -> Result<(u32, u32), DispatchError> { let market = T::MarketCommons::market(market_id)?; let (ids_len, disputes_len) = match market.status { MarketStatus::Reported => { diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 86b180c12..355fcc12e 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -15,7 +15,7 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{CacheSize, Config, Disputes, MarketIdOf, Pallet}; +use crate::{CacheSize, Config, Disputes, Pallet}; use alloc::{vec, vec::Vec}; use frame_support::{ dispatch::Weight, @@ -487,7 +487,8 @@ mod tests { BoundedVec::try_from(vec![dispute.clone()]).unwrap(), ); - AuthorizedOutcomeReports::::insert(market_id, OutcomeReport::Scalar(19)); + let report = AuthorityReport { resolve_at: None, outcome: OutcomeReport::Scalar(19) }; + AuthorizedOutcomeReports::::insert(market_id, report); let juror = 20; let block_number = 21; @@ -508,7 +509,7 @@ mod tests { let authorized_report_after = AuthorizedOutcomeReports::::get(market_id).unwrap(); - assert_eq!(authorized_report_after, OutcomeReport::Scalar(190_000_000_000)); + assert_eq!(authorized_report_after.outcome, OutcomeReport::Scalar(190_000_000_000)); let vote_after = Votes::::get(market_id, juror).unwrap(); assert_eq!(vote_after, (block_number, OutcomeReport::Scalar(220_000_000_000))); @@ -545,7 +546,8 @@ mod tests { BoundedVec::try_from(vec![dispute.clone()]).unwrap(), ); - AuthorizedOutcomeReports::::insert(market_id, OutcomeReport::Scalar(19)); + let report = AuthorityReport { resolve_at: None, outcome: OutcomeReport::Scalar(19) }; + AuthorizedOutcomeReports::::insert(market_id, report); let juror = 20; let vote = (21, OutcomeReport::Scalar(22)); @@ -562,7 +564,7 @@ mod tests { let authorized_report_after = AuthorizedOutcomeReports::::get(market_id).unwrap(); - assert_eq!(authorized_report_after, OutcomeReport::Scalar(19)); + assert_eq!(authorized_report_after.outcome, OutcomeReport::Scalar(19)); let vote_after = Votes::::get(market_id, juror).unwrap(); assert_eq!(vote_after, vote); diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 4e2de8bdc..4318db3f1 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2019,7 +2019,17 @@ fn it_allows_to_dispute_the_outcome_of_a_market() { fn dispute_fails_authority_reported_already() { ExtBuilder::default().build().execute_with(|| { let end = 2; - simple_create_categorical_market(MarketCreation::Permissionless, 0..end, ScoringRule::CPMM); + assert_ok!(PredictionMarkets::create_market( + Origin::signed(ALICE), + BOB, + MarketPeriod::Block(0..end), + get_deadlines(), + gen_metadata(2), + MarketCreation::Permissionless, + MarketType::Categorical(::MinCategories::get()), + MarketDisputeMechanism::Authorized(FRED), + ScoringRule::CPMM, + )); // Run to the end of the trading phase. let market = MarketCommons::market(&0).unwrap(); @@ -2035,6 +2045,12 @@ fn dispute_fails_authority_reported_already() { let dispute_at = grace_period + 2; run_to_block(dispute_at); + assert_ok!(PredictionMarkets::dispute( + Origin::signed(CHARLIE), + 0, + OutcomeReport::Categorical(0) + )); + assert_ok!(Authorized::authorize_market_outcome( Origin::signed(FRED), 0, @@ -2042,7 +2058,7 @@ fn dispute_fails_authority_reported_already() { )); assert_noop!( - PredictionMarkets::dispute(Origin::signed(CHARLIE), 1, OutcomeReport::Categorical(0)), + PredictionMarkets::dispute(Origin::signed(CHARLIE), 0, OutcomeReport::Categorical(1)), AuthorizedError::::AuthorityAlreadyReported ); }); @@ -2324,7 +2340,7 @@ fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { let disputes = crate::Disputes::::get(0); assert_eq!(disputes.len(), 3); - run_blocks(market.deadlines.dispute_duration); + run_blocks(::CorrectionPeriod::get()); let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); let disputes = crate::Disputes::::get(0); @@ -2901,18 +2917,6 @@ fn authorized_correctly_resolves_disputed_market() { OutcomeReport::Categorical(1) )); - // Fred authorizses an outcome, but fat-fingers it on the first try. - assert_ok!(Authorized::authorize_market_outcome( - Origin::signed(FRED), - 0, - OutcomeReport::Categorical(0) - )); - assert_ok!(Authorized::authorize_market_outcome( - Origin::signed(FRED), - 0, - OutcomeReport::Categorical(1) - )); - let dispute_at_1 = dispute_at_0 + 1; run_to_block(dispute_at_1); assert_ok!(PredictionMarkets::dispute( @@ -2928,6 +2932,18 @@ fn authorized_correctly_resolves_disputed_market() { OutcomeReport::Categorical(1) )); + // Fred authorizses an outcome, but fat-fingers it on the first try. + assert_ok!(Authorized::authorize_market_outcome( + Origin::signed(FRED), + 0, + OutcomeReport::Categorical(0) + )); + assert_ok!(Authorized::authorize_market_outcome( + Origin::signed(FRED), + 0, + OutcomeReport::Categorical(1) + )); + let market = MarketCommons::market(&0).unwrap(); assert_eq!(market.status, MarketStatus::Disputed); @@ -2947,21 +2963,21 @@ fn authorized_correctly_resolves_disputed_market() { // make sure the old mappings of market id per dispute block are erased let market_ids_1 = MarketIdsPerDisputeBlock::::get( - dispute_at_0 + market.deadlines.dispute_duration, + dispute_at_0 + ::CorrectionPeriod::get(), ); assert_eq!(market_ids_1.len(), 0); let market_ids_2 = MarketIdsPerDisputeBlock::::get( - dispute_at_1 + market.deadlines.dispute_duration, + dispute_at_1 + ::CorrectionPeriod::get(), ); assert_eq!(market_ids_2.len(), 0); let market_ids_3 = MarketIdsPerDisputeBlock::::get( - dispute_at_2 + market.deadlines.dispute_duration, + dispute_at_2 + ::CorrectionPeriod::get(), ); assert_eq!(market_ids_3.len(), 1); - run_blocks(market.deadlines.dispute_duration); + run_blocks(::CorrectionPeriod::get()); let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); @@ -3039,7 +3055,7 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { let charlie_reserved = Balances::reserved_balance(&CHARLIE); assert_eq!(charlie_reserved, DisputeBond::get()); - run_blocks(market.deadlines.dispute_duration); + run_blocks(::CorrectionPeriod::get()); let market_after = MarketCommons::market(&market_id).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); let disputes = crate::Disputes::::get(0); From 19585bf4a6e76c69e5b71243e2542b0acf811eb0 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 2 Nov 2022 07:22:10 +0100 Subject: [PATCH 07/93] avoid in place migration --- zrml/prediction-markets/src/migrations.rs | 36 +++++++++++++++-------- 1 file changed, 24 insertions(+), 12 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 355fcc12e..06de5b1d9 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -75,22 +75,27 @@ where } log::info!("AddFieldToAuthorityReport: Starting..."); - for (key, value) in + let mut new_storage_map = Vec::new(); + for (key, old_value) in storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { - if let Some(old_value) = value { + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + + if let Some(outcome) = old_value { let resolve_at: Option = None; - let new_value = AuthorityReport { resolve_at, outcome: old_value }; - put_storage_value::>>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - &key, - Some(new_value), - ); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + let new_value = AuthorityReport { resolve_at, outcome }; + new_storage_map.push((key, new_value)); } + } - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + for (key, new_value) in new_storage_map { + put_storage_value::>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &key, + Some(new_value), + ); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); @@ -134,6 +139,7 @@ where } log::info!("UpdateMarketIdsPerDisputeBlock: Starting..."); + let mut new_storage_map = Vec::new(); for (key, mut bounded_vec) in storage_iter::< BoundedVec<::MarketId, CacheSize>, >(PREDICTION_MARKETS, MARKET_IDS_PER_DISPUTE_BLOCK) @@ -148,14 +154,20 @@ where MarketDisputeMechanism::SimpleDisputes => true, } } else { + // no market for id in MarketIdsPerDisputeBlock false } }); + + new_storage_map.push((key, bounded_vec)); + } + + for (key, new_bounded_vec) in new_storage_map { put_storage_value::::MarketId, CacheSize>>( PREDICTION_MARKETS, MARKET_IDS_PER_DISPUTE_BLOCK, &key, - bounded_vec, + new_bounded_vec, ); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } From 1e7fd668ee1a3b88da08a4304f3ce7337ac837ea Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 2 Nov 2022 08:35:38 +0100 Subject: [PATCH 08/93] default to oracle report for authorized --- primitives/src/constants/mock.rs | 1 + runtime/battery-station/src/parameters.rs | 1 + runtime/common/src/lib.rs | 1 + runtime/zeitgeist/src/parameters.rs | 1 + zrml/authorized/src/lib.rs | 41 +++++++++++++++++++++++ zrml/prediction-markets/src/benchmarks.rs | 9 ----- zrml/prediction-markets/src/migrations.rs | 2 +- zrml/prediction-markets/src/mock.rs | 15 +++++---- zrml/prediction-markets/src/tests.rs | 8 +++-- 9 files changed, 60 insertions(+), 19 deletions(-) diff --git a/primitives/src/constants/mock.rs b/primitives/src/constants/mock.rs index d3d8c44ca..a1890a8ac 100644 --- a/primitives/src/constants/mock.rs +++ b/primitives/src/constants/mock.rs @@ -10,6 +10,7 @@ use orml_traits::parameter_type_with_key; // Authorized parameter_types! { + pub const AuthorityReportPeriod: BlockNumber = 10; pub const AuthorizedPalletId: PalletId = PalletId(*b"zge/atzd"); pub const CorrectionPeriod: BlockNumber = 4; } diff --git a/runtime/battery-station/src/parameters.rs b/runtime/battery-station/src/parameters.rs index ab638fb30..75b86657f 100644 --- a/runtime/battery-station/src/parameters.rs +++ b/runtime/battery-station/src/parameters.rs @@ -47,6 +47,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized + pub const AuthorityReportPeriod: BlockNumber = 4 * BLOCKS_PER_DAY; pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; pub const CorrectionPeriod: BlockNumber = 3 * BLOCKS_PER_HOUR; diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index b3499ea20..d78bfb122 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -864,6 +864,7 @@ macro_rules! impl_config_traits { impl parachain_info::Config for Runtime {} impl zrml_authorized::Config for Runtime { + type AuthorityReportPeriod = AuthorityReportPeriod; type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = zrml_prediction_markets::Pallet; type Event = Event; diff --git a/runtime/zeitgeist/src/parameters.rs b/runtime/zeitgeist/src/parameters.rs index a3d460374..c8c6c7037 100644 --- a/runtime/zeitgeist/src/parameters.rs +++ b/runtime/zeitgeist/src/parameters.rs @@ -47,6 +47,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized + pub const AuthorityReportPeriod: BlockNumber = 6 * BLOCKS_PER_DAY; pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; pub const CorrectionPeriod: BlockNumber = 6 * BLOCKS_PER_HOUR; diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 593642c35..04dfb0b49 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -65,6 +65,7 @@ mod pallet { #[pallet::call] impl Pallet { + // TODO update benchmark /// Overwrites already provided outcomes for the same market and account. #[frame_support::transactional] #[pallet::weight(T::WeightInfo::authorize_market_outcome())] @@ -95,10 +96,44 @@ mod pallet { Ok(()) } + + // TODO update benchmark + /// In case, that the authority did not report in time, + /// the market will resolve to the report of the oracle. + #[frame_support::transactional] + #[pallet::weight(5000)] + pub fn resolve_to_oracle_report( + origin: OriginFor, + market_id: MarketIdOf, + ) -> DispatchResult { + ensure_signed(origin)?; + let market = T::MarketCommons::market(&market_id)?; + ensure!(market.status == MarketStatus::Disputed, Error::::MarketIsNotDisputed); + if let MarketDisputeMechanism::Authorized(_) = market.dispute_mechanism { + ensure!( + !AuthorizedOutcomeReports::::contains_key(market_id), + Error::::AuthorityReportPresent + ); + let report = market.report.as_ref().ok_or(Error::::MarketIsNotReported)?; + let now = frame_system::Pallet::::block_number(); + ensure!( + report.at.saturating_add(T::AuthorityReportPeriod::get()) < now, + Error::::TimeLeftForAuthority + ); + T::DisputeResolution::resolve(&market_id, &market)?; + Ok(()) + } else { + Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) + } + } } #[pallet::config] pub trait Config: frame_system::Config { + /// The period in which the authority has to report. + #[pallet::constant] + type AuthorityReportPeriod: Get; + /// Event type Event: From> + IsType<::Event>; @@ -139,6 +174,12 @@ mod pallet { OutcomeMismatch, /// The authority already made its report. AuthorityAlreadyReported, + /// The authority has still time left to authorize an outcome. + TimeLeftForAuthority, + /// The market should be reported at this point. + MarketIsNotReported, + /// The authority has reported in time. + AuthorityReportPresent, } #[pallet::event] diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 070671d5d..4f02cca70 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -765,7 +765,6 @@ benchmarks! { dispute_authorized { let d in 0..(T::MaxDisputes::get() - 1); - let b in 0..63; let report_outcome = OutcomeReport::Scalar(u128::MAX); let (caller, market_id) = create_close_and_report_market::( @@ -793,14 +792,6 @@ benchmarks! { Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; } - let now = frame_system::Pallet::::block_number(); - for i in 0..b { - MarketIdsPerDisputeBlock::::try_mutate( - now, - |ids| ids.try_push(i.into()), - ).unwrap(); - } - let dispute_outcome = OutcomeReport::Scalar((d + 1).into()); let call = Call::::dispute { market_id, outcome: dispute_outcome }; }: { diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 06de5b1d9..3f3302bff 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -80,7 +80,7 @@ where storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - + if let Some(outcome) = old_value { let resolve_at: Option = None; let new_value = AuthorityReport { resolve_at, outcome }; diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 68f78bc43..fb18916ed 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -35,13 +35,13 @@ use sp_runtime::{ use substrate_fixed::{types::extra::U33, FixedI128, FixedU128}; use zeitgeist_primitives::{ constants::mock::{ - AuthorizedPalletId, BalanceFractionalDecimals, BlockHashCount, CorrectionPeriod, - CourtCaseDuration, CourtPalletId, DisputeFactor, ExistentialDeposit, ExistentialDeposits, - ExitFee, GetNativeCurrencyId, LiquidityMiningPalletId, MaxApprovals, MaxAssets, - MaxCategories, MaxDisputeDuration, MaxDisputes, MaxEditReasonLen, MaxGracePeriod, - MaxInRatio, MaxMarketPeriod, MaxOracleDuration, MaxOutRatio, MaxRejectReasonLen, - MaxReserves, MaxSubsidyPeriod, MaxSwapFee, MaxTotalWeight, MaxWeight, MinAssets, - MinCategories, MinDisputeDuration, MinLiquidity, MinOracleDuration, MinSubsidy, + AuthorityReportPeriod, AuthorizedPalletId, BalanceFractionalDecimals, BlockHashCount, + CorrectionPeriod, CourtCaseDuration, CourtPalletId, DisputeFactor, ExistentialDeposit, + ExistentialDeposits, ExitFee, GetNativeCurrencyId, LiquidityMiningPalletId, MaxApprovals, + MaxAssets, MaxCategories, MaxDisputeDuration, MaxDisputes, MaxEditReasonLen, + MaxGracePeriod, MaxInRatio, MaxMarketPeriod, MaxOracleDuration, MaxOutRatio, + MaxRejectReasonLen, MaxReserves, MaxSubsidyPeriod, MaxSwapFee, MaxTotalWeight, MaxWeight, + MinAssets, MinCategories, MinDisputeDuration, MinLiquidity, MinOracleDuration, MinSubsidy, MinSubsidyPeriod, MinWeight, MinimumPeriod, PmPalletId, SimpleDisputesPalletId, StakeWeight, SwapsPalletId, TreasuryPalletId, BASE, CENT, MILLISECS_PER_BLOCK, }, @@ -212,6 +212,7 @@ impl pallet_timestamp::Config for Runtime { } impl zrml_authorized::Config for Runtime { + type AuthorityReportPeriod = AuthorityReportPeriod; type CorrectionPeriod = CorrectionPeriod; type Event = Event; type DisputeResolution = prediction_markets::Pallet; diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 4318db3f1..dec9a1003 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2340,7 +2340,9 @@ fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { let disputes = crate::Disputes::::get(0); assert_eq!(disputes.len(), 3); - run_blocks(::CorrectionPeriod::get()); + run_blocks(::AuthorityReportPeriod::get() + 1); + assert_ok!(Authorized::resolve_to_oracle_report(Origin::signed(FRED), 0)); + let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); let disputes = crate::Disputes::::get(0); @@ -3055,7 +3057,9 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { let charlie_reserved = Balances::reserved_balance(&CHARLIE); assert_eq!(charlie_reserved, DisputeBond::get()); - run_blocks(::CorrectionPeriod::get()); + run_blocks(::AuthorityReportPeriod::get() + 1); + assert_ok!(Authorized::resolve_to_oracle_report(Origin::signed(FRED), market_id)); + let market_after = MarketCommons::market(&market_id).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); let disputes = crate::Disputes::::get(0); From c9adaf30233c807939b6b053307b9d7447301949 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 2 Nov 2022 10:28:03 +0100 Subject: [PATCH 09/93] wip --- primitives/src/market.rs | 2 +- primitives/src/traits/dispute_api.rs | 7 +++ zrml/authorized/src/lib.rs | 54 ++++++++--------------- zrml/court/src/lib.rs | 12 +++++ zrml/prediction-markets/src/lib.rs | 43 ++++++++++++++++++ zrml/prediction-markets/src/migrations.rs | 40 ++++++++++++++--- zrml/simple-disputes/src/lib.rs | 12 +++++ 7 files changed, 128 insertions(+), 42 deletions(-) diff --git a/primitives/src/market.rs b/primitives/src/market.rs index 5eea2e465..eeb3f7ad6 100644 --- a/primitives/src/market.rs +++ b/primitives/src/market.rs @@ -217,7 +217,7 @@ pub struct Report { #[derive(Clone, Decode, Encode, Eq, MaxEncodedLen, PartialEq, RuntimeDebug, TypeInfo)] pub struct AuthorityReport { - pub resolve_at: Option, + pub resolve_at: BlockNumber, pub outcome: OutcomeReport, } diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index cba90b597..5faca4fc8 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -58,6 +58,13 @@ pub trait DisputeApi { market_id: &Self::MarketId, market: &Market, ) -> Result, DispatchError>; + + // TODO doc comment + fn is_fail( + disputes: &[MarketDispute], + market_id: &Self::MarketId, + market: &Market, + ) -> Result; } pub trait DisputeResolutionApi { diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 04dfb0b49..1b04e61ec 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -91,41 +91,11 @@ mod pallet { let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); T::DisputeResolution::add_auto_resolve(&market_id, correction_period_ends_at)?; - let report = AuthorityReport { resolve_at: Some(correction_period_ends_at), outcome }; + let report = AuthorityReport { resolve_at: correction_period_ends_at, outcome }; AuthorizedOutcomeReports::::insert(market_id, report); Ok(()) } - - // TODO update benchmark - /// In case, that the authority did not report in time, - /// the market will resolve to the report of the oracle. - #[frame_support::transactional] - #[pallet::weight(5000)] - pub fn resolve_to_oracle_report( - origin: OriginFor, - market_id: MarketIdOf, - ) -> DispatchResult { - ensure_signed(origin)?; - let market = T::MarketCommons::market(&market_id)?; - ensure!(market.status == MarketStatus::Disputed, Error::::MarketIsNotDisputed); - if let MarketDisputeMechanism::Authorized(_) = market.dispute_mechanism { - ensure!( - !AuthorizedOutcomeReports::::contains_key(market_id), - Error::::AuthorityReportPresent - ); - let report = market.report.as_ref().ok_or(Error::::MarketIsNotReported)?; - let now = frame_system::Pallet::::block_number(); - ensure!( - report.at.saturating_add(T::AuthorityReportPeriod::get()) < now, - Error::::TimeLeftForAuthority - ); - T::DisputeResolution::resolve(&market_id, &market)?; - Ok(()) - } else { - Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) - } - } } #[pallet::config] @@ -174,12 +144,8 @@ mod pallet { OutcomeMismatch, /// The authority already made its report. AuthorityAlreadyReported, - /// The authority has still time left to authorize an outcome. - TimeLeftForAuthority, /// The market should be reported at this point. MarketIsNotReported, - /// The authority has reported in time. - AuthorityReportPresent, } #[pallet::event] @@ -199,7 +165,7 @@ mod pallet { T: Config, { fn get_auto_resolve(market_id: &MarketIdOf) -> Option { - AuthorizedOutcomeReports::::get(market_id).map(|report| report.resolve_at).flatten() + AuthorizedOutcomeReports::::get(market_id).map(|report| report.resolve_at) } fn remove_auto_resolve(market_id: &MarketIdOf) { @@ -262,6 +228,22 @@ mod pallet { Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) } } + + fn is_fail( + _: &[MarketDispute], + market_id: &Self::MarketId, + market: &Market>, + ) -> Result { + if let MarketDisputeMechanism::Authorized(_) = market.dispute_mechanism { + let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); + let report = market.report.as_ref().ok_or(Error::::MarketIsNotReported)?; + let now = frame_system::Pallet::::block_number(); + let is_expired = report.at.saturating_add(T::AuthorityReportPeriod::get()) < now; + Ok(is_unreported && is_expired) + } else { + Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) + } + } } impl AuthorizedPalletApi for Pallet where T: Config {} diff --git a/zrml/court/src/lib.rs b/zrml/court/src/lib.rs index a24766ab8..8943eabbd 100644 --- a/zrml/court/src/lib.rs +++ b/zrml/court/src/lib.rs @@ -565,6 +565,18 @@ mod pallet { Ok(None) } + + fn is_fail( + _: &[MarketDispute], + _: &Self::MarketId, + market: &Market>, + ) -> Result { + if market.dispute_mechanism != MarketDisputeMechanism::Court { + return Err(Error::::MarketDoesNotHaveCourtMechanism.into()); + } + // TODO when does court fail? + Ok(false) + } } impl CourtPalletApi for Pallet where T: Config {} diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 5633a420c..e2ba07ffd 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -487,6 +487,45 @@ mod pallet { Ok((Some(T::WeightInfo::dispute_authorized(num_disputes, CacheSize::get()))).into()) } + /// Resolve the market, when the dispute mechanism failed. + /// + /// # Weight + /// + /// Complexity: `O(n)`, where `n` is the number of outstanding disputes. + // TODO update benchmarks + #[pallet::weight(5000)] + #[transactional] + pub fn resolve_failed_mdm( + origin: OriginFor, + #[pallet::compact] market_id: MarketIdOf, + ) -> DispatchResultWithPostInfo { + let who = ensure_signed(origin)?; + let market = T::MarketCommons::market(&market_id)?; + ensure!( + market.status == MarketStatus::Disputed, + Error::::InvalidMarketStatus + ); + let disputes = Disputes::::get(market_id); + let is_fail = match market.dispute_mechanism { + MarketDisputeMechanism::Authorized(_) => { + T::Authorized::is_fail(&disputes, &market_id, &market)? + } + MarketDisputeMechanism::Court => { + T::Court::is_fail(&disputes, &market_id, &market)? + } + MarketDisputeMechanism::SimpleDisputes => { + T::SimpleDisputes::is_fail(&disputes, &market_id, &market)? + } + }; + ensure!(is_fail, Error::::DisputeMechanismNotFailed); + + Self::on_resolution(&market_id, &market); + + Self::deposit_event(Event::DisputeMechanismFailed(market_id)); + + Ok(().into()) + } + /// Create a permissionless market, buy complete sets and deploy a pool with specified /// liquidity. /// @@ -1396,6 +1435,8 @@ mod pallet { /// Someone is trying to call `dispute` with the same outcome that is currently /// registered on-chain. CannotDisputeSameOutcome, + /// The market dispute mechanism has not failed. + DisputeMechanismNotFailed, /// Only creator is able to edit the market. EditorNotCreator, /// EditReason's length greater than MaxEditReasonLen. @@ -1488,6 +1529,8 @@ mod pallet { BadOnInitialize, /// A complete set of assets has been bought \[market_id, amount_per_asset, buyer\] BoughtCompleteSet(MarketIdOf, BalanceOf, ::AccountId), + /// A market dispute mechansim failed \[market_id\] + DisputeMechanismFailed(MarketIdOf), /// A market has been approved \[market_id, new_market_status\] MarketApproved(MarketIdOf, MarketStatus), /// A market has been created \[market_id, market_account, market\] diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 3f3302bff..a79961f4b 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -17,6 +17,7 @@ use crate::{CacheSize, Config, Disputes, Pallet}; use alloc::{vec, vec::Vec}; +use sp_runtime::traits::One; use frame_support::{ dispatch::Weight, log, @@ -25,6 +26,7 @@ use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, BoundedVec, }; +use sp_runtime::traits::Saturating; use parity_scale_codec::EncodeLike; use zeitgeist_primitives::{ constants::BASE, @@ -76,13 +78,15 @@ where log::info!("AddFieldToAuthorityReport: Starting..."); let mut new_storage_map = Vec::new(); + let now = >::block_number(); for (key, old_value) in storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); if let Some(outcome) = old_value { - let resolve_at: Option = None; + let resolve_at: T::BlockNumber = + now.saturating_add(T::AuthorityReportPeriod::get()); let new_value = AuthorityReport { resolve_at, outcome }; new_storage_map.push((key, new_value)); } @@ -118,10 +122,13 @@ where pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); // Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` -impl OnRuntimeUpgrade for UpdateMarketIdsPerDisputeBlock +impl OnRuntimeUpgrade for UpdateMarketIdsPerDisputeBlock where ::MarketId: EncodeLike<<::MarketCommons as MarketCommonsPalletApi>::MarketId>, + ::MarketId: EncodeLike< + <::MarketCommons as MarketCommonsPalletApi>::MarketId, + > { fn on_runtime_upgrade() -> Weight where @@ -140,8 +147,9 @@ where log::info!("UpdateMarketIdsPerDisputeBlock: Starting..."); let mut new_storage_map = Vec::new(); + let mut authorized_ids = Vec::new(); for (key, mut bounded_vec) in storage_iter::< - BoundedVec<::MarketId, CacheSize>, + BoundedVec<<::MarketCommons as MarketCommonsPalletApi>::MarketId, CacheSize>, >(PREDICTION_MARKETS, MARKET_IDS_PER_DISPUTE_BLOCK) { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); @@ -149,7 +157,10 @@ where bounded_vec.retain(|id| { if let Ok(market) = MarketCommonsPallet::::market(id) { match market.dispute_mechanism { - MarketDisputeMechanism::Authorized(_) => false, + MarketDisputeMechanism::Authorized(_) => { + authorized_ids.push(id); + false + } MarketDisputeMechanism::Court => false, MarketDisputeMechanism::SimpleDisputes => true, } @@ -163,7 +174,7 @@ where } for (key, new_bounded_vec) in new_storage_map { - put_storage_value::::MarketId, CacheSize>>( + put_storage_value::::MarketCommons as MarketCommonsPalletApi>::MarketId, CacheSize>>( PREDICTION_MARKETS, MARKET_IDS_PER_DISPUTE_BLOCK, &key, @@ -172,6 +183,25 @@ where total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } + let now = >::block_number(); + for id in authorized_ids { + let mut resolve_at: T::BlockNumber = + now.saturating_add(::AuthorityReportPeriod::get()); + let mut ids = crate::MarketIdsPerDisputeBlock::::get(resolve_at); + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + + while ids.is_full() { + resolve_at = resolve_at.saturating_add(One::one()); + ids = crate::MarketIdsPerDisputeBlock::::get(resolve_at); + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + } + // is_full check above to ensure, that we can force_push + ids.force_push(*id); + crate::MarketIdsPerDisputeBlock::::insert(resolve_at, ids); + + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + } + StorageVersion::new(PREDICTION_MARKETS_NEXT_STORAGE_VERSION).put::>(); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); log::info!("UpdateMarketIdsPerDisputeBlock: Done!"); diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index 454a8863e..51a150088 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -174,6 +174,18 @@ mod pallet { } Ok(Self::get_auto_resolve(disputes, market)) } + + fn is_fail( + _: &[MarketDispute], + _: &Self::MarketId, + market: &Market>, + ) -> Result { + if market.dispute_mechanism != MarketDisputeMechanism::SimpleDisputes { + return Err(Error::::MarketDoesNotHaveSimpleDisputesMechanism.into()); + } + // TODO when does simple disputes fail? + Ok(false) + } } impl SimpleDisputesPalletApi for Pallet where T: Config {} From 500060de1ca45d675d35a70fd9051787759710d7 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 2 Nov 2022 15:36:17 +0100 Subject: [PATCH 10/93] wip --- primitives/src/traits/dispute_api.rs | 23 ++++++++++++++--- zrml/authorized/src/lib.rs | 11 ++++----- zrml/authorized/src/mock.rs | 4 ++- zrml/authorized/src/tests.rs | 4 +-- zrml/prediction-markets/src/lib.rs | 21 ++++++---------- zrml/prediction-markets/src/migrations.rs | 30 +++++++++++------------ zrml/prediction-markets/src/tests.rs | 13 +++++++--- zrml/simple-disputes/src/lib.rs | 9 ++++--- 8 files changed, 67 insertions(+), 48 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 5faca4fc8..36274c0c7 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -52,14 +52,24 @@ pub trait DisputeApi { market: &Market, ) -> Result, DispatchError>; - // TODO doc comment + /// Query the future resolution block of a disputed market. + /// Fails if the market dispute mechanism does not belong to the actual dispute mechanism. + /// + /// # Returns + /// + /// Returns the future resolution block if available, otherwise `None`. fn get_auto_resolve( disputes: &[MarketDispute], market_id: &Self::MarketId, market: &Market, ) -> Result, DispatchError>; - // TODO doc comment + /// Query if the dispute mechanism failed for a dispute market. + /// Fails if the market dispute mechanism does not belong to the actual dispute mechanism. + /// + /// # Returns + /// + /// Returns true, when the dispute mechanism failed. Otherwise false. fn is_fail( disputes: &[MarketDispute], market_id: &Self::MarketId, @@ -86,12 +96,17 @@ pub trait DisputeResolutionApi { market: &Market, ) -> Result; - // TODO doc comment + /// Add a future block resolution of a disputed market. + /// Fails in case of a storage overflow. + /// + /// # Returns + /// + /// Returns Ok if the market id was added succesfully. fn add_auto_resolve( market_id: &Self::MarketId, resolution: Self::BlockNumber, ) -> DispatchResult; - // TODO doc comment + /// Remove a future block resolution of a disputed market. fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber); } diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 1b04e61ec..9ff6e08f1 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -134,6 +134,8 @@ mod pallet { #[pallet::error] pub enum Error { + /// The authority already made its report. + AuthorityAlreadyReported, /// An unauthorized account attempts to submit a report. NotAuthorizedForThisMarket, /// The market unexpectedly has the incorrect dispute mechanism. @@ -142,8 +144,6 @@ mod pallet { MarketIsNotDisputed, /// The report does not match the market's type. OutcomeMismatch, - /// The authority already made its report. - AuthorityAlreadyReported, /// The market should be reported at this point. MarketIsNotReported, } @@ -169,9 +169,9 @@ mod pallet { } fn remove_auto_resolve(market_id: &MarketIdOf) { - Self::get_auto_resolve(market_id).map(|resolve_at| { - T::DisputeResolution::remove_auto_resolve(&market_id, resolve_at); - }); + if let Some(resolve_at) = Self::get_auto_resolve(market_id) { + T::DisputeResolution::remove_auto_resolve(market_id, resolve_at); + } } } @@ -248,7 +248,6 @@ mod pallet { impl AuthorizedPalletApi for Pallet where T: Config {} - // TODO storage migration from OutcomeReport to AuthorityReport /// Maps the market id to the outcome reported by the authorized account. #[pallet::storage] #[pallet::getter(fn outcomes)] diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 15889217a..8a4f45580 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -25,7 +25,8 @@ use sp_runtime::{ }; use zeitgeist_primitives::{ constants::mock::{ - AuthorizedPalletId, BlockHashCount, CorrectionPeriod, MaxReserves, MinimumPeriod, BASE, + AuthorityReportPeriod, AuthorizedPalletId, BlockHashCount, CorrectionPeriod, MaxReserves, + MinimumPeriod, BASE, }, traits::DisputeResolutionApi, types::{ @@ -80,6 +81,7 @@ impl DisputeResolutionApi for NoopResolution { } impl crate::Config for Runtime { + type AuthorityReportPeriod = AuthorityReportPeriod; type Event = (); type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = NoopResolution; diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index d3ee7b421..a7335b7a3 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -39,7 +39,7 @@ fn authorize_market_outcome_inserts_a_new_outcome() { OutcomeReport::Scalar(1) )); let now = frame_system::Pallet::::block_number(); - let resolve_at = Some(now + ::CorrectionPeriod::get()); + let resolve_at = now + ::CorrectionPeriod::get(); assert_eq!( AuthorizedOutcomeReports::::get(0).unwrap(), AuthorityReport { outcome: OutcomeReport::Scalar(1), resolve_at } @@ -188,7 +188,7 @@ fn authorize_market_outcome_allows_using_same_account_on_multiple_markets() { OutcomeReport::Scalar(456) )); let now = frame_system::Pallet::::block_number(); - let resolve_at = Some(now + ::CorrectionPeriod::get()); + let resolve_at = now + ::CorrectionPeriod::get(); assert_eq!( AuthorizedOutcomeReports::::get(0).unwrap(), AuthorityReport { outcome: OutcomeReport::Scalar(123), resolve_at } diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index e2ba07ffd..f4666869b 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -499,27 +499,22 @@ mod pallet { origin: OriginFor, #[pallet::compact] market_id: MarketIdOf, ) -> DispatchResultWithPostInfo { - let who = ensure_signed(origin)?; + ensure_signed(origin)?; let market = T::MarketCommons::market(&market_id)?; - ensure!( - market.status == MarketStatus::Disputed, - Error::::InvalidMarketStatus - ); + ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); let disputes = Disputes::::get(market_id); let is_fail = match market.dispute_mechanism { MarketDisputeMechanism::Authorized(_) => { T::Authorized::is_fail(&disputes, &market_id, &market)? } - MarketDisputeMechanism::Court => { - T::Court::is_fail(&disputes, &market_id, &market)? - } + MarketDisputeMechanism::Court => T::Court::is_fail(&disputes, &market_id, &market)?, MarketDisputeMechanism::SimpleDisputes => { T::SimpleDisputes::is_fail(&disputes, &market_id, &market)? } }; ensure!(is_fail, Error::::DisputeMechanismNotFailed); - Self::on_resolution(&market_id, &market); + Self::on_resolution(&market_id, &market)?; Self::deposit_event(Event::DisputeMechanismFailed(market_id)); @@ -1737,8 +1732,6 @@ mod pallet { #[pallet::storage] pub type LastTimeFrame = StorageValue<_, TimeFrame>; - // TODO storage migration: delete Court and Authorized markets from here, - // TODO simple disputes is okay as it is /// A mapping of market identifiers to the block they were disputed at. /// A market only ends up here if it was disputed. #[pallet::storage] @@ -1905,13 +1898,13 @@ mod pallet { let disputes = Disputes::::get(market_id); let auto_resolve_block_opt = match market.dispute_mechanism { MarketDisputeMechanism::Authorized(_) => { - T::Authorized::get_auto_resolve(&disputes, &market_id, &market)? + T::Authorized::get_auto_resolve(&disputes, market_id, &market)? } MarketDisputeMechanism::Court => { - T::Court::get_auto_resolve(&disputes, &market_id, &market)? + T::Court::get_auto_resolve(&disputes, market_id, &market)? } MarketDisputeMechanism::SimpleDisputes => { - T::SimpleDisputes::get_auto_resolve(&disputes, &market_id, &market)? + T::SimpleDisputes::get_auto_resolve(&disputes, market_id, &market)? } }; if let Some(auto_resolve_block) = auto_resolve_block_opt { diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index a79961f4b..325c2a712 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -15,9 +15,8 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{CacheSize, Config, Disputes, Pallet}; +use crate::{CacheSize, Config, Disputes, MarketIdOf, Pallet}; use alloc::{vec, vec::Vec}; -use sp_runtime::traits::One; use frame_support::{ dispatch::Weight, log, @@ -26,8 +25,8 @@ use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, BoundedVec, }; -use sp_runtime::traits::Saturating; use parity_scale_codec::EncodeLike; +use sp_runtime::traits::{One, Saturating}; use zeitgeist_primitives::{ constants::BASE, types::{AuthorityReport, MarketDisputeMechanism, MarketType, OutcomeReport}, @@ -122,13 +121,14 @@ where pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); // Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` -impl OnRuntimeUpgrade for UpdateMarketIdsPerDisputeBlock +impl OnRuntimeUpgrade + for UpdateMarketIdsPerDisputeBlock where ::MarketId: EncodeLike<<::MarketCommons as MarketCommonsPalletApi>::MarketId>, ::MarketId: EncodeLike< <::MarketCommons as MarketCommonsPalletApi>::MarketId, - > + >, { fn on_runtime_upgrade() -> Weight where @@ -148,17 +148,17 @@ where let mut new_storage_map = Vec::new(); let mut authorized_ids = Vec::new(); - for (key, mut bounded_vec) in storage_iter::< - BoundedVec<<::MarketCommons as MarketCommonsPalletApi>::MarketId, CacheSize>, - >(PREDICTION_MARKETS, MARKET_IDS_PER_DISPUTE_BLOCK) - { + for (key, mut bounded_vec) in storage_iter::, CacheSize>>( + PREDICTION_MARKETS, + MARKET_IDS_PER_DISPUTE_BLOCK, + ) { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); bounded_vec.retain(|id| { - if let Ok(market) = MarketCommonsPallet::::market(id) { + if let Ok(market) = ::MarketCommons::market(id) { match market.dispute_mechanism { MarketDisputeMechanism::Authorized(_) => { - authorized_ids.push(id); + authorized_ids.push(*id); false } MarketDisputeMechanism::Court => false, @@ -174,7 +174,7 @@ where } for (key, new_bounded_vec) in new_storage_map { - put_storage_value::::MarketCommons as MarketCommonsPalletApi>::MarketId, CacheSize>>( + put_storage_value::, CacheSize>>( PREDICTION_MARKETS, MARKET_IDS_PER_DISPUTE_BLOCK, &key, @@ -196,7 +196,7 @@ where total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); } // is_full check above to ensure, that we can force_push - ids.force_push(*id); + ids.force_push(id); crate::MarketIdsPerDisputeBlock::::insert(resolve_at, ids); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); @@ -529,7 +529,7 @@ mod tests { BoundedVec::try_from(vec![dispute.clone()]).unwrap(), ); - let report = AuthorityReport { resolve_at: None, outcome: OutcomeReport::Scalar(19) }; + let report = AuthorityReport { resolve_at: 42, outcome: OutcomeReport::Scalar(19) }; AuthorizedOutcomeReports::::insert(market_id, report); let juror = 20; @@ -588,7 +588,7 @@ mod tests { BoundedVec::try_from(vec![dispute.clone()]).unwrap(), ); - let report = AuthorityReport { resolve_at: None, outcome: OutcomeReport::Scalar(19) }; + let report = AuthorityReport { resolve_at: 42, outcome: OutcomeReport::Scalar(19) }; AuthorizedOutcomeReports::::insert(market_id, report); let juror = 20; diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index dec9a1003..27e3fa144 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2341,7 +2341,7 @@ fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { assert_eq!(disputes.len(), 3); run_blocks(::AuthorityReportPeriod::get() + 1); - assert_ok!(Authorized::resolve_to_oracle_report(Origin::signed(FRED), 0)); + assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), 0)); let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); @@ -3057,8 +3057,15 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { let charlie_reserved = Balances::reserved_balance(&CHARLIE); assert_eq!(charlie_reserved, DisputeBond::get()); - run_blocks(::AuthorityReportPeriod::get() + 1); - assert_ok!(Authorized::resolve_to_oracle_report(Origin::signed(FRED), market_id)); + run_blocks(::AuthorityReportPeriod::get()); + assert_noop!( + PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id), + Error::::DisputeMechanismNotFailed + ); + + run_blocks(1); + // AuthorityReportPeriod is now over + assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id)); let market_after = MarketCommons::market(&market_id).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index 51a150088..774ea2dd2 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -112,9 +112,12 @@ mod pallet { market_id: &MarketIdOf, market: &Market>, ) { - Self::get_auto_resolve(disputes, market).map(|dispute_duration_ends_at_block| { - T::DisputeResolution::remove_auto_resolve(market_id, dispute_duration_ends_at_block) - }); + if let Some(dispute_duration_ends_at_block) = Self::get_auto_resolve(disputes, market) { + T::DisputeResolution::remove_auto_resolve( + market_id, + dispute_duration_ends_at_block, + ); + } } } From d4387018bfe8896e7193a1ebd1c8e6e47063b29a Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 3 Nov 2022 09:28:25 +0100 Subject: [PATCH 11/93] change test --- zrml/prediction-markets/src/tests.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 27e3fa144..457b5ff3b 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2979,7 +2979,12 @@ fn authorized_correctly_resolves_disputed_market() { ); assert_eq!(market_ids_3.len(), 1); - run_blocks(::CorrectionPeriod::get()); + run_blocks(::CorrectionPeriod::get() - 1); + + let market_after = MarketCommons::market(&0).unwrap(); + assert_eq!(market_after.status, MarketStatus::Disputed); + + run_blocks(1); let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); From 26b5dde41a5c21a004ba677cc269aed73ec6b001 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 3 Nov 2022 12:01:16 +0100 Subject: [PATCH 12/93] fix benchmark --- zrml/prediction-markets/src/lib.rs | 7 ++----- zrml/prediction-markets/src/weights.rs | 6 ++---- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index f4666869b..5a263fc61 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -435,10 +435,7 @@ mod pallet { /// # Weight /// /// Complexity: `O(n)`, where `n` is the number of outstanding disputes. - #[pallet::weight(T::WeightInfo::dispute_authorized( - T::MaxDisputes::get(), - CacheSize::get() - ))] + #[pallet::weight(T::WeightInfo::dispute_authorized(T::MaxDisputes::get()))] #[transactional] pub fn dispute( origin: OriginFor, @@ -484,7 +481,7 @@ mod pallet { market_dispute, )); // TODO(#782): add court benchmark - Ok((Some(T::WeightInfo::dispute_authorized(num_disputes, CacheSize::get()))).into()) + Ok((Some(T::WeightInfo::dispute_authorized(num_disputes))).into()) } /// Resolve the market, when the dispute mechanism failed. diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index 2b8e1c4e4..d3ff1eb23 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -59,7 +59,7 @@ pub trait WeightInfoZeitgeist { fn edit_market(m: u32) -> Weight; fn deploy_swap_pool_for_market_future_pool(a: u32, o: u32) -> Weight; fn deploy_swap_pool_for_market_open_pool(a: u32) -> Weight; - fn dispute_authorized(d: u32, b: u32) -> Weight; + fn dispute_authorized(d: u32) -> Weight; fn handle_expired_advised_market() -> Weight; fn internal_resolve_categorical_reported() -> Weight; fn internal_resolve_categorical_disputed(d: u32) -> Weight; @@ -290,10 +290,8 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons Markets (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) - fn dispute_authorized(_d: u32, b: u32) -> Weight { + fn dispute_authorized(_d: u32) -> Weight { (77_511_000 as Weight) - // Standard Error: 3_000 - .saturating_add((95_000 as Weight).saturating_mul(b as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } From 52fa258c009666fefb7359bca8958bbd5a87992e Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 3 Nov 2022 12:44:01 +0100 Subject: [PATCH 13/93] add resolve_failed_mdm benchmarks --- zrml/prediction-markets/src/benchmarks.rs | 71 +++++++++++++++++++++++ 1 file changed, 71 insertions(+) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 4f02cca70..3bfeda48e 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -798,6 +798,77 @@ benchmarks! { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } + resolve_failed_mdm_authorized_scalar { + let d in 1..T::MaxDisputes::get(); + + let report_outcome = OutcomeReport::Scalar(u128::MAX); + let (caller, market_id) = create_close_and_report_market::( + MarketCreation::Permissionless, + MarketType::Scalar(0u128..=u128::MAX), + report_outcome, + )?; + + T::MarketCommons::mutate_market(&market_id, |market| { + let admin = account("admin", 0, 0); + market.dispute_mechanism = MarketDisputeMechanism::Authorized(admin); + Ok(()) + })?; + + let market = T::MarketCommons::market(&market_id)?; + if let MarketType::Scalar(range) = market.market_type { + assert!((d as u128) < *range.end()); + } else { + panic!("Must create scalar market"); + } + for i in 1..=d { + let outcome = OutcomeReport::Scalar(i.into()); + let disputor = account("disputor", i, 0); + T::AssetManager::deposit(Asset::Ztg, &disputor, (u128::MAX).saturated_into())?; + Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; + } + + let call = Call::::resolve_failed_mdm { market_id }; + }: { + call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; + } verify { + assert_last_event::(Event::DisputeMechanismFailed::(market_id).into()); + } + + resolve_failed_mdm_authorized_categorical { + let d in 1..T::MaxDisputes::get(); + + let categories = T::MaxCategories::get(); + let (caller, market_id) = + setup_reported_categorical_market_with_pool::( + categories.into(), + OutcomeReport::Categorical(0u16) + )?; + + T::MarketCommons::mutate_market(&market_id, |market| { + let admin = account("admin", 0, 0); + market.dispute_mechanism = MarketDisputeMechanism::Authorized(admin); + 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 call = Call::::resolve_failed_mdm { market_id }; + }: { + call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; + } verify { + assert_last_event::(Event::DisputeMechanismFailed::(market_id).into()); + } + handle_expired_advised_market { let (_, market_id) = create_market_common::( MarketCreation::Advised, From 773fe577b589608bc40911e19d6569e3420e7412 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 4 Nov 2022 15:17:09 +0100 Subject: [PATCH 14/93] correct benchmarks --- runtime/common/src/lib.rs | 14 +++++++--- zrml/authorized/src/benchmarks.rs | 2 +- zrml/authorized/src/lib.rs | 11 ++++---- zrml/authorized/src/mock.rs | 2 +- zrml/prediction-markets/src/benchmarks.rs | 16 ++++++++++- zrml/prediction-markets/src/lib.rs | 22 ++++++++++++--- zrml/prediction-markets/src/migrations.rs | 10 +++---- zrml/prediction-markets/src/mock.rs | 2 +- zrml/prediction-markets/src/weights.rs | 33 +++++++++++++++++++++++ 9 files changed, 92 insertions(+), 20 deletions(-) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index d78bfb122..7268d1d15 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -58,7 +58,11 @@ macro_rules! decl_common_types { frame_system::ChainContext, Runtime, AllPalletsWithSystem, - zrml_prediction_markets::migrations::TransformScalarMarketsToFixedPoint, + ( + zrml_prediction_markets::migrations::TransformScalarMarketsToFixedPoint, + zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, + zrml_prediction_markets::migrations::AddFieldToAuthorityReport, + ), >; #[cfg(not(feature = "parachain"))] @@ -68,7 +72,11 @@ macro_rules! decl_common_types { frame_system::ChainContext, Runtime, AllPalletsWithSystem, - zrml_prediction_markets::migrations::TransformScalarMarketsToFixedPoint, + ( + zrml_prediction_markets::migrations::TransformScalarMarketsToFixedPoint, + zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, + zrml_prediction_markets::migrations::AddFieldToAuthorityReport, + ) >; pub type Header = generic::Header; @@ -868,7 +876,7 @@ macro_rules! impl_config_traits { type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = zrml_prediction_markets::Pallet; type Event = Event; - type MarketCommons = MarketCommons; + type MarketCommonsAuthorized = MarketCommons; type PalletId = AuthorizedPalletId; type WeightInfo = zrml_authorized::weights::WeightInfo; } diff --git a/zrml/authorized/src/benchmarks.rs b/zrml/authorized/src/benchmarks.rs index 34bac4c46..ed0ca9162 100644 --- a/zrml/authorized/src/benchmarks.rs +++ b/zrml/authorized/src/benchmarks.rs @@ -33,7 +33,7 @@ benchmarks! { authorize_market_outcome { let caller: T::AccountId = whitelisted_caller(); let market = market_mock::(caller.clone()); - T::MarketCommons::push_market(market).unwrap(); + T::MarketCommonsAuthorized::push_market(market).unwrap(); }: _(RawOrigin::Signed(caller), 0u32.into(), OutcomeReport::Scalar(1)) } diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 9ff6e08f1..fbd882b75 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -58,10 +58,11 @@ mod pallet { pub(crate) type BalanceOf = as Currency<::AccountId>>::Balance; pub(crate) type CurrencyOf = - <::MarketCommons as MarketCommonsPalletApi>::Currency; + <::MarketCommonsAuthorized as MarketCommonsPalletApi>::Currency; pub(crate) type MarketIdOf = - <::MarketCommons as MarketCommonsPalletApi>::MarketId; - pub(crate) type MomentOf = <::MarketCommons as MarketCommonsPalletApi>::Moment; + <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId; + pub(crate) type MomentOf = + <::MarketCommonsAuthorized as MarketCommonsPalletApi>::Moment; #[pallet::call] impl Pallet { @@ -75,7 +76,7 @@ mod pallet { outcome: OutcomeReport, ) -> DispatchResult { let who = ensure_signed(origin)?; - let market = T::MarketCommons::market(&market_id)?; + let market = T::MarketCommonsAuthorized::market(&market_id)?; ensure!(market.status == MarketStatus::Disputed, Error::::MarketIsNotDisputed); ensure!(market.matches_outcome_report(&outcome), Error::::OutcomeMismatch); if let MarketDisputeMechanism::Authorized(ref account_id) = market.dispute_mechanism { @@ -119,7 +120,7 @@ mod pallet { >; /// Market commons - type MarketCommons: MarketCommonsPalletApi< + type MarketCommonsAuthorized: MarketCommonsPalletApi< AccountId = Self::AccountId, BlockNumber = Self::BlockNumber, >; diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 8a4f45580..2447b0161 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -85,7 +85,7 @@ impl crate::Config for Runtime { type Event = (); type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = NoopResolution; - type MarketCommons = MarketCommons; + type MarketCommonsAuthorized = MarketCommons; type PalletId = AuthorizedPalletId; type WeightInfo = crate::weights::WeightInfo; } diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 65010e21b..588940082 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -218,7 +218,7 @@ fn setup_reported_categorical_market_with_pool::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; } + let authority_report_period = ::AuthorityReportPeriod::get(); + let now = >::block_number(); + // authorized mdm fails after the AuthorityReportPeriod + >::set_block_number( + now + authority_report_period.saturated_into() + 1u64.saturated_into() + ); + let call = Call::::resolve_failed_mdm { market_id }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; @@ -865,6 +872,13 @@ benchmarks! { Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; } + let authority_report_period = ::AuthorityReportPeriod::get(); + let now = >::block_number(); + // authorized mdm fails after the AuthorityReportPeriod + >::set_block_number( + now + authority_report_period.saturated_into() + 1u64.saturated_into() + ); + let call = Call::::resolve_failed_mdm { market_id }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 5a263fc61..0f5f2b9e3 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -458,6 +458,7 @@ mod pallet { &who, default_dispute_bond::(disputes.len()), )?; + // TODO(#782): use multiple benchmarks paths for different dispute mechanisms match market.dispute_mechanism { MarketDisputeMechanism::Authorized(_) => { T::Authorized::on_dispute(&disputes, &market_id, &market)? @@ -480,7 +481,6 @@ mod pallet { MarketStatus::Disputed, market_dispute, )); - // TODO(#782): add court benchmark Ok((Some(T::WeightInfo::dispute_authorized(num_disputes))).into()) } @@ -490,7 +490,10 @@ mod pallet { /// /// Complexity: `O(n)`, where `n` is the number of outstanding disputes. // TODO update benchmarks - #[pallet::weight(5000)] + #[pallet::weight( + T::WeightInfo::resolve_failed_mdm_authorized_categorical(T::MaxDisputes::get()) + .max(T::WeightInfo::resolve_failed_mdm_authorized_scalar(T::MaxDisputes::get())) + )] #[transactional] pub fn resolve_failed_mdm( origin: OriginFor, @@ -500,6 +503,8 @@ mod pallet { let market = T::MarketCommons::market(&market_id)?; ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); let disputes = Disputes::::get(market_id); + let disputes_len = disputes.len() as u32; + // TODO(#782): use multiple benchmarks paths for different dispute mechanisms let is_fail = match market.dispute_mechanism { MarketDisputeMechanism::Authorized(_) => { T::Authorized::is_fail(&disputes, &market_id, &market)? @@ -515,7 +520,16 @@ mod pallet { Self::deposit_event(Event::DisputeMechanismFailed(market_id)); - Ok(().into()) + let weight = match market.market_type { + MarketType::Scalar(_) => { + T::WeightInfo::resolve_failed_mdm_authorized_scalar(disputes_len) + } + MarketType::Categorical(_) => { + T::WeightInfo::resolve_failed_mdm_authorized_categorical(disputes_len) + } + }; + + Ok((Some(weight)).into()) } /// Create a permissionless market, buy complete sets and deploy a pool with specified @@ -1893,6 +1907,7 @@ mod pallet { } MarketStatus::Disputed => { let disputes = Disputes::::get(market_id); + // TODO(#782): use multiple benchmarks paths for different dispute mechanisms let auto_resolve_block_opt = match market.dispute_mechanism { MarketDisputeMechanism::Authorized(_) => { T::Authorized::get_auto_resolve(&disputes, market_id, &market)? @@ -2249,6 +2264,7 @@ mod pallet { report.outcome.clone() } MarketStatus::Disputed => { + // TODO(#782): use multiple benchmarks paths for different dispute mechanisms // Try to get the outcome of the MDM. If the MDM failed to resolve, default to // the oracle's report. let resolved_outcome_option = match market.dispute_mechanism { diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 325c2a712..41c81d22e 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -57,7 +57,7 @@ impl OnRuntim for AddFieldToAuthorityReport where ::MarketId: EncodeLike< - <::MarketCommons as MarketCommonsPalletApi>::MarketId, + <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId, >, { fn on_runtime_upgrade() -> Weight @@ -84,8 +84,8 @@ where total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); if let Some(outcome) = old_value { - let resolve_at: T::BlockNumber = - now.saturating_add(T::AuthorityReportPeriod::get()); + let resolve_at: T::BlockNumber = now + .saturating_add(::AuthorityReportPeriod::get()); let new_value = AuthorityReport { resolve_at, outcome }; new_storage_map.push((key, new_value)); } @@ -127,7 +127,7 @@ where ::MarketId: EncodeLike<<::MarketCommons as MarketCommonsPalletApi>::MarketId>, ::MarketId: EncodeLike< - <::MarketCommons as MarketCommonsPalletApi>::MarketId, + <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId, >, { fn on_runtime_upgrade() -> Weight @@ -229,7 +229,7 @@ impl where ::MarketId: EncodeLike< - <::MarketCommons as MarketCommonsPalletApi>::MarketId, + <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId, >, ::MarketId: EncodeLike<<::MarketCommons as MarketCommonsPalletApi>::MarketId>, diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index fb18916ed..606b52578 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -216,7 +216,7 @@ impl zrml_authorized::Config for Runtime { type CorrectionPeriod = CorrectionPeriod; type Event = Event; type DisputeResolution = prediction_markets::Pallet; - type MarketCommons = MarketCommons; + type MarketCommonsAuthorized = MarketCommons; type PalletId = AuthorizedPalletId; type WeightInfo = zrml_authorized::weights::WeightInfo; } diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index d3ff1eb23..7eee398a5 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -60,6 +60,8 @@ pub trait WeightInfoZeitgeist { fn deploy_swap_pool_for_market_future_pool(a: u32, o: u32) -> Weight; fn deploy_swap_pool_for_market_open_pool(a: u32) -> Weight; fn dispute_authorized(d: u32) -> Weight; + fn resolve_failed_mdm_authorized_scalar(d: u32) -> Weight; + fn resolve_failed_mdm_authorized_categorical(d: u32) -> Weight; fn handle_expired_advised_market() -> Weight; fn internal_resolve_categorical_reported() -> Weight; fn internal_resolve_categorical_disputed(d: u32) -> Weight; @@ -295,6 +297,37 @@ impl WeightInfoZeitgeist for WeightInfo { .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } + // Storage: MarketCommons Markets (r:1 w:1) + // Storage: PredictionMarkets Disputes (r:1 w:1) + // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) + // Storage: Balances Reserves (r:2 w:2) + // Storage: System Account (r:2 w:2) + // Storage: MarketCommons MarketPool (r:1 w:0) + fn resolve_failed_mdm_authorized_scalar(d: u32) -> Weight { + (80_390_000 as Weight) + // Standard Error: 25_000 + .saturating_add((20_931_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(6 as Weight)) + .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(d as Weight))) + .saturating_add(T::DbWeight::get().writes(4 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) + // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) + // Storage: Balances Reserves (r:2 w:2) + // Storage: System Account (r:2 w:2) + // Storage: MarketCommons MarketPool (r:1 w:0) + // Storage: Swaps Pools (r:1 w:1) + fn resolve_failed_mdm_authorized_categorical(d: u32) -> Weight { + (103_383_000 as Weight) + // Standard Error: 31_000 + .saturating_add((20_787_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(5 as Weight)) + .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(d as Weight))) + } // Storage: Balances Reserves (r:1 w:1) // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets MarketIdsForEdit (r:0 w:1) From 8428c245c96b3dfc283d64d1b72e676897be1dd9 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 4 Nov 2022 15:34:10 +0100 Subject: [PATCH 15/93] fix nightly clippy --- zrml/prediction-markets/src/benchmarks.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 588940082..9d7f9ad05 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -145,7 +145,7 @@ fn setup_redeem_shares_common( } else if let MarketType::Scalar(range) = market_type { outcome = OutcomeReport::Scalar(*range.end()); } else { - panic!("setup_redeem_shares_common: Unsupported market type: {:?}", market_type); + panic!("setup_redeem_shares_common: Unsupported market type: {market_type:?}"); } Pallet::::do_buy_complete_set( From e72449806efbc2e34b4a3f78c1cbf98082f77a0c Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Sat, 5 Nov 2022 20:52:42 +0100 Subject: [PATCH 16/93] fix after merge --- zrml/prediction-markets/src/benchmarks.rs | 5 ++--- zrml/prediction-markets/src/lib.rs | 4 ++-- zrml/prediction-markets/src/migrations.rs | 2 +- zrml/prediction-markets/src/tests.rs | 2 +- 4 files changed, 6 insertions(+), 7 deletions(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index abc93dd47..d4752865e 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -808,8 +808,7 @@ benchmarks! { )?; T::MarketCommons::mutate_market(&market_id, |market| { - let admin = account("admin", 0, 0); - market.dispute_mechanism = MarketDisputeMechanism::Authorized(admin); + market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; @@ -852,7 +851,7 @@ benchmarks! { T::MarketCommons::mutate_market(&market_id, |market| { let admin = account("admin", 0, 0); - market.dispute_mechanism = MarketDisputeMechanism::Authorized(admin); + market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index e080d3eef..a40314ac3 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -506,7 +506,7 @@ mod pallet { let disputes_len = disputes.len() as u32; // TODO(#782): use multiple benchmarks paths for different dispute mechanisms let is_fail = match market.dispute_mechanism { - MarketDisputeMechanism::Authorized(_) => { + MarketDisputeMechanism::Authorized => { T::Authorized::is_fail(&disputes, &market_id, &market)? } MarketDisputeMechanism::Court => T::Court::is_fail(&disputes, &market_id, &market)?, @@ -1909,7 +1909,7 @@ mod pallet { let disputes = Disputes::::get(market_id); // TODO(#782): use multiple benchmarks paths for different dispute mechanisms let auto_resolve_block_opt = match market.dispute_mechanism { - MarketDisputeMechanism::Authorized(_) => { + MarketDisputeMechanism::Authorized => { T::Authorized::get_auto_resolve(&disputes, market_id, &market)? } MarketDisputeMechanism::Court => { diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 899c028cc..d8963e218 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -157,7 +157,7 @@ where bounded_vec.retain(|id| { if let Ok(market) = ::MarketCommons::market(id) { match market.dispute_mechanism { - MarketDisputeMechanism::Authorized(_) => { + MarketDisputeMechanism::Authorized => { authorized_ids.push(*id); false } diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 7cf695f76..ac40139ea 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2027,7 +2027,7 @@ fn dispute_fails_authority_reported_already() { gen_metadata(2), MarketCreation::Permissionless, MarketType::Categorical(::MinCategories::get()), - MarketDisputeMechanism::Authorized(FRED), + MarketDisputeMechanism::Authorized, ScoringRule::CPMM, )); From db7670d68aab084dbbcc4b664f26430793afe5e3 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 7 Nov 2022 10:15:42 +0100 Subject: [PATCH 17/93] fix admin for Authorized --- zrml/prediction-markets/src/benchmarks.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index d4752865e..a7f422cf6 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -850,7 +850,6 @@ benchmarks! { )?; T::MarketCommons::mutate_market(&market_id, |market| { - let admin = account("admin", 0, 0); market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; From 535ea0086cdfdf48865794c22e6e6d950d312c7b Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 24 Nov 2022 14:34:55 +0100 Subject: [PATCH 18/93] fix global disputes --- zrml/prediction-markets/src/lib.rs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 2ef48e541..a8a032d95 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -1300,10 +1300,10 @@ mod pallet { ); // add report outcome to voting choices - if let Some(report) = market.report { + if let Some(report) = &market.report { T::GlobalDisputes::push_voting_outcome( &market_id, - report.outcome, + report.outcome.clone(), &report.by, >::zero(), )?; @@ -1319,9 +1319,16 @@ mod pallet { )?; } + // TODO(#372): Allow court with global disputes. // ensure, that global disputes controls the resolution now // it does not end after the dispute period now, but after the global dispute end - Self::remove_last_dispute_from_market_ids_per_dispute_block(&disputes, &market_id)?; + if let Some(auto_resolve_block) = + T::SimpleDisputes::get_auto_resolve(&disputes, &market_id, &market)? + { + MarketIdsPerDisputeBlock::::mutate(auto_resolve_block, |ids| { + remove_item::, _>(ids, &market_id); + }); + } let now = >::block_number(); let global_dispute_end = now.saturating_add(T::GlobalDisputePeriod::get()); From 81db3eef57f22f5a2085b14c7d387d13cf170ccb Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 25 Nov 2022 12:51:34 +0100 Subject: [PATCH 19/93] add migration tests --- runtime/battery-station/src/parameters.rs | 2 +- zrml/authorized/src/lib.rs | 2 +- zrml/prediction-markets/src/lib.rs | 2 +- zrml/prediction-markets/src/migrations.rs | 286 +++++++++++++++++++++- 4 files changed, 285 insertions(+), 7 deletions(-) diff --git a/runtime/battery-station/src/parameters.rs b/runtime/battery-station/src/parameters.rs index 5d2374922..d6de551a5 100644 --- a/runtime/battery-station/src/parameters.rs +++ b/runtime/battery-station/src/parameters.rs @@ -50,7 +50,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized - pub const AuthorityReportPeriod: BlockNumber = 4 * BLOCKS_PER_DAY; + pub const AuthorityReportPeriod: BlockNumber = 6 * BLOCKS_PER_DAY; pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; pub const CorrectionPeriod: BlockNumber = 3 * BLOCKS_PER_HOUR; diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 576be3165..27f2df92f 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -53,7 +53,7 @@ mod pallet { use zrml_market_commons::MarketCommonsPalletApi; /// The current storage version. - const STORAGE_VERSION: StorageVersion = StorageVersion::new(2); + const STORAGE_VERSION: StorageVersion = StorageVersion::new(3); pub(crate) type BalanceOf = as Currency<::AccountId>>::Balance; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index a8a032d95..f585399b9 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -70,7 +70,7 @@ mod pallet { use zrml_market_commons::MarketCommonsPalletApi; /// The current storage version. - const STORAGE_VERSION: StorageVersion = StorageVersion::new(6); + const STORAGE_VERSION: StorageVersion = StorageVersion::new(7); pub(crate) type BalanceOf = <::AssetManager as MultiCurrency< ::AccountId, diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index d8963e218..dc375f84d 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -41,14 +41,14 @@ const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; const PREDICTION_MARKETS: &[u8] = b"PredictionMarkets"; const MARKET_IDS_PER_DISPUTE_BLOCK: &[u8] = b"MarketIdsPerDisputeBlock"; -const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 1; -const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 2; +const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; +const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; const COURT_REQUIRED_STORAGE_VERSION: u16 = 1; const COURT_NEXT_STORAGE_VERSION: u16 = 2; const MARKET_COMMONS_REQUIRED_STORAGE_VERSION: u16 = 3; const MARKET_COMMONS_NEXT_STORAGE_VERSION: u16 = 4; -const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 5; -const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 6; +const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 6; +const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 7; pub struct AddFieldToAuthorityReport(PhantomData); @@ -109,15 +109,107 @@ where #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { + for (key, old_value) in storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { + if let Some(outcome) = old_value { + // save outcome and check it in post_upgrade + unimplemented!(); + } + } Ok(()) } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { + let now = >::block_number(); + assert_eq!(::AuthorityReportPeriod::get(), 43_200u32.into()); + for (key, new_value) in storage_iter::>>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { + if let Some(AuthorityReport { resolve_at, outcome }) = new_value { + assert_eq!(resolve_at, now.checked_add(::AuthorityReportPeriod::get()).unwrap()); + } + } Ok(()) } } +#[cfg(test)] +mod tests_authorized { + use super::*; + use crate::mock::{ExtBuilder, Runtime}; + use frame_support::Twox64Concat; + use zeitgeist_primitives::types::{MarketId, OutcomeReport}; + + #[test] + fn on_runtime_upgrade_increments_the_storage_versions() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + AddFieldToAuthorityReport::::on_runtime_upgrade(); + let authorized_version = StorageVersion::get::>(); + assert_eq!(authorized_version, AUTHORIZED_NEXT_STORAGE_VERSION); + }); + } + + #[test] + fn on_runtime_sets_new_struct_with_resolve_at() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + + >::set_block_number(10_000); + + let hash = crate::migrations::utility::key_to_hash::(0); + let outcome = OutcomeReport::Categorical(42u16); + put_storage_value::>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &hash, + Some(outcome.clone()), + ); + + AddFieldToAuthorityReport::::on_runtime_upgrade(); + + let now = >::block_number(); + let resolve_at: ::BlockNumber = now + .saturating_add(::AuthorityReportPeriod::get()); + let expected = Some(AuthorityReport { resolve_at, outcome }); + + let actual = frame_support::migration::get_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) + .unwrap(); + assert_eq!(expected, actual); + }); + } + + #[test] + fn on_runtime_is_noop_if_versions_are_not_correct() { + ExtBuilder::default().build().execute_with(|| { + // storage migration already executed (storage version is incremented already) + StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); + + let hash = crate::migrations::utility::key_to_hash::(0); + let outcome = OutcomeReport::Categorical(42u16); + let now = >::block_number(); + let resolve_at: ::BlockNumber = now + .saturating_add(::AuthorityReportPeriod::get()); + let report = AuthorityReport { resolve_at, outcome }; + put_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, Some(report.clone())); + + AddFieldToAuthorityReport::::on_runtime_upgrade(); + + let actual = frame_support::migration::get_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) + .unwrap(); + assert_eq!(Some(report), actual); + }); + } + + fn set_up_chain() { + StorageVersion::new(AUTHORIZED_REQUIRED_STORAGE_VERSION).put::>(); + } +} + pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); // Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` @@ -219,6 +311,192 @@ where } } +#[cfg(test)] +mod tests_auto_resolution { + use super::*; + use crate::{ + mock::{ExtBuilder, Runtime}, + MomentOf, + }; + use zeitgeist_primitives::types::{ + Deadlines, MarketCreation, MarketDisputeMechanism, MarketId, MarketPeriod, MarketStatus, + OutcomeReport, Report, ScoringRule, + }; + use zrml_market_commons::Markets; + + type Market = zeitgeist_primitives::types::Market< + ::AccountId, + ::BlockNumber, + MomentOf, + >; + + #[test] + fn on_runtime_upgrade_increments_the_storage_versions() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + let prediction_markets_version = StorageVersion::get::>(); + assert_eq!(prediction_markets_version, PREDICTION_MARKETS_NEXT_STORAGE_VERSION); + }); + } + + #[test] + fn on_runtime_updates_market_ids_per_dispute_block_authorized_ids_full() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + + let market_id = MarketId::from(0u64); + let market = get_market(MarketDisputeMechanism::Authorized); + + Markets::::insert(market_id, market); + + let now = >::block_number(); + crate::MarketIdsPerDisputeBlock::::insert( + now, + BoundedVec::try_from(vec![market_id]).unwrap(), + ); + + let resolve_at = now + .saturating_add(::AuthorityReportPeriod::get()); + + let full_ids: Vec = (MarketId::from(1u64)..=MarketId::from(64u64)).collect(); + + for id in full_ids.clone() { + let market = get_market(MarketDisputeMechanism::SimpleDisputes); + Markets::::insert(id, market); + } + + crate::MarketIdsPerDisputeBlock::::insert( + resolve_at, + BoundedVec::try_from(full_ids.clone()).unwrap(), + ); + assert!(crate::MarketIdsPerDisputeBlock::::get(resolve_at).is_full()); + + UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + + assert_eq!(crate::MarketIdsPerDisputeBlock::::get(resolve_at), full_ids); + assert!( + !crate::MarketIdsPerDisputeBlock::::get(resolve_at).contains(&market_id) + ); + // store market id at the next block + assert_eq!( + crate::MarketIdsPerDisputeBlock::::get(resolve_at + 1), + vec![market_id] + ); + }); + } + + #[test] + fn on_runtime_updates_market_ids_per_dispute_block_simple_disputes_unchanged() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + + let market_id = MarketId::from(0u64); + let market = get_market(MarketDisputeMechanism::SimpleDisputes); + + Markets::::insert(market_id, market); + + crate::MarketIdsPerDisputeBlock::::insert( + 0, + BoundedVec::try_from(vec![market_id]).unwrap(), + ); + + UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + + // unchanged for simple disputes + assert_eq!(crate::MarketIdsPerDisputeBlock::::get(0), vec![market_id]); + }); + } + + #[test] + fn on_runtime_updates_market_ids_per_dispute_block_authorized_deleted() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + + let market_id = MarketId::from(0u64); + let market = get_market(MarketDisputeMechanism::Authorized); + + Markets::::insert(market_id, market); + + crate::MarketIdsPerDisputeBlock::::insert( + 0, + BoundedVec::try_from(vec![market_id]).unwrap(), + ); + + UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + + // authority controls market resolution now (no auto resolution) + assert!(crate::MarketIdsPerDisputeBlock::::get(0).is_empty()); + }); + } + + #[test] + fn on_runtime_updates_market_ids_per_dispute_block_court_deletion() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + + let market_id = MarketId::from(0u64); + let market = get_market(MarketDisputeMechanism::Court); + Markets::::insert(market_id, market); + + crate::MarketIdsPerDisputeBlock::::insert( + 0, + BoundedVec::try_from(vec![market_id]).unwrap(), + ); + + UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + + // court auto resolution is deactivated for now (court is disabled) + assert!(crate::MarketIdsPerDisputeBlock::::get(0).is_empty()); + }); + } + + #[test] + fn on_runtime_is_noop_if_versions_are_not_correct() { + ExtBuilder::default().build().execute_with(|| { + // Don't set up chain to signal that storage is already up to date. + + let market_id = MarketId::from(0u64); + let market = get_market(MarketDisputeMechanism::Court); + Markets::::insert(market_id, market); + + crate::MarketIdsPerDisputeBlock::::insert( + 0, + BoundedVec::try_from(vec![market_id]).unwrap(), + ); + + UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + + // normally court auto resolution gets deleted with the storage migration, + // but because storage version is already updated, + // it is not + assert_eq!(crate::MarketIdsPerDisputeBlock::::get(0), vec![market_id]); + }); + } + + fn get_market(mdm: MarketDisputeMechanism) -> Market { + Market { + creator: 1, + creation: MarketCreation::Permissionless, + creator_fee: 2, + oracle: 3, + metadata: vec![4, 5], + market_type: MarketType::Categorical(14), + period: MarketPeriod::Block(6..7), + deadlines: Deadlines { grace_period: 8, oracle_duration: 9, dispute_duration: 10 }, + scoring_rule: ScoringRule::CPMM, + status: MarketStatus::Disputed, + report: Some(Report { at: 11, by: 12, outcome: OutcomeReport::Categorical(13) }), + resolved_outcome: Some(OutcomeReport::Categorical(13)), + dispute_mechanism: mdm, + } + } + + fn set_up_chain() { + StorageVersion::new(PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION).put::>(); + } +} + pub struct TransformScalarMarketsToFixedPoint(PhantomData); // Transform all scalar intervals by BASE, thereby turning every scalar position into a fixed point From a02b3c9db73a891ec6e69d3db2d79d02c2f20709 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 25 Nov 2022 14:14:56 +0100 Subject: [PATCH 20/93] delete 0.3.7 storage migration --- runtime/common/src/lib.rs | 4 - zrml/prediction-markets/src/migrations.rs | 555 +++------------------- 2 files changed, 78 insertions(+), 481 deletions(-) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 2fd368429..f794d89a0 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -59,8 +59,6 @@ macro_rules! decl_common_types { Runtime, AllPalletsWithSystem, ( - zrml_market_commons::migrations::UpdateMarketsForAuthorizedMDM, - zrml_prediction_markets::migrations::TransformScalarMarketsToFixedPoint, zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, zrml_prediction_markets::migrations::AddFieldToAuthorityReport, ) @@ -74,8 +72,6 @@ macro_rules! decl_common_types { Runtime, AllPalletsWithSystem, ( - zrml_market_commons::migrations::UpdateMarketsForAuthorizedMDM, - zrml_prediction_markets::migrations::TransformScalarMarketsToFixedPoint, zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, zrml_prediction_markets::migrations::AddFieldToAuthorityReport, ) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index dc375f84d..d663121c6 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -15,8 +15,8 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{CacheSize, Config, Disputes, MarketIdOf, Pallet}; -use alloc::{vec, vec::Vec}; +use crate::{CacheSize, Config, MarketIdOf, Pallet}; +use alloc::{vec::Vec}; use frame_support::{ dispatch::Weight, log, @@ -28,187 +28,22 @@ use frame_support::{ use parity_scale_codec::EncodeLike; use sp_runtime::traits::{One, Saturating}; use zeitgeist_primitives::{ - constants::BASE, - types::{AuthorityReport, MarketDisputeMechanism, MarketType, OutcomeReport}, + types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}, }; -use zrml_authorized::{AuthorizedOutcomeReports, Pallet as AuthorizedPallet}; -use zrml_court::{Pallet as CourtPallet, Votes}; -use zrml_market_commons::{MarketCommonsPalletApi, Pallet as MarketCommonsPallet}; - -const AUTHORIZED: &[u8] = b"Authorized"; -const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; +use zrml_authorized::{Pallet as AuthorizedPallet}; +use zrml_market_commons::{MarketCommonsPalletApi}; const PREDICTION_MARKETS: &[u8] = b"PredictionMarkets"; const MARKET_IDS_PER_DISPUTE_BLOCK: &[u8] = b"MarketIdsPerDisputeBlock"; -const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; -const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; -const COURT_REQUIRED_STORAGE_VERSION: u16 = 1; -const COURT_NEXT_STORAGE_VERSION: u16 = 2; -const MARKET_COMMONS_REQUIRED_STORAGE_VERSION: u16 = 3; -const MARKET_COMMONS_NEXT_STORAGE_VERSION: u16 = 4; const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 6; const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 7; -pub struct AddFieldToAuthorityReport(PhantomData); - -// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. -impl OnRuntimeUpgrade - for AddFieldToAuthorityReport -where - ::MarketId: EncodeLike< - <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId, - >, -{ - fn on_runtime_upgrade() -> Weight - where - T: Config, - { - let mut total_weight = T::DbWeight::get().reads(1); - let authorized_version = StorageVersion::get::>(); - if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION { - log::info!( - "AddFieldToAuthorityReport: authorized version is {:?}, require {:?};", - authorized_version, - AUTHORIZED_REQUIRED_STORAGE_VERSION, - ); - return total_weight; - } - log::info!("AddFieldToAuthorityReport: Starting..."); - - let mut new_storage_map = Vec::new(); - let now = >::block_number(); - for (key, old_value) in - storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) - { - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - - if let Some(outcome) = old_value { - let resolve_at: T::BlockNumber = now - .saturating_add(::AuthorityReportPeriod::get()); - let new_value = AuthorityReport { resolve_at, outcome }; - new_storage_map.push((key, new_value)); - } - } - - for (key, new_value) in new_storage_map { - put_storage_value::>>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - &key, - Some(new_value), - ); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - } - - StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::info!("AddFieldToAuthorityReport: Done!"); - total_weight - } - - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result<(), &'static str> { - for (key, old_value) in storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { - if let Some(outcome) = old_value { - // save outcome and check it in post_upgrade - unimplemented!(); - } - } - Ok(()) - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade() -> Result<(), &'static str> { - let now = >::block_number(); - assert_eq!(::AuthorityReportPeriod::get(), 43_200u32.into()); - for (key, new_value) in storage_iter::>>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { - if let Some(AuthorityReport { resolve_at, outcome }) = new_value { - assert_eq!(resolve_at, now.checked_add(::AuthorityReportPeriod::get()).unwrap()); - } - } - Ok(()) - } -} - -#[cfg(test)] -mod tests_authorized { - use super::*; - use crate::mock::{ExtBuilder, Runtime}; - use frame_support::Twox64Concat; - use zeitgeist_primitives::types::{MarketId, OutcomeReport}; - - #[test] - fn on_runtime_upgrade_increments_the_storage_versions() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - AddFieldToAuthorityReport::::on_runtime_upgrade(); - let authorized_version = StorageVersion::get::>(); - assert_eq!(authorized_version, AUTHORIZED_NEXT_STORAGE_VERSION); - }); - } - - #[test] - fn on_runtime_sets_new_struct_with_resolve_at() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - - >::set_block_number(10_000); - - let hash = crate::migrations::utility::key_to_hash::(0); - let outcome = OutcomeReport::Categorical(42u16); - put_storage_value::>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - &hash, - Some(outcome.clone()), - ); - - AddFieldToAuthorityReport::::on_runtime_upgrade(); - - let now = >::block_number(); - let resolve_at: ::BlockNumber = now - .saturating_add(::AuthorityReportPeriod::get()); - let expected = Some(AuthorityReport { resolve_at, outcome }); - - let actual = frame_support::migration::get_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) - .unwrap(); - assert_eq!(expected, actual); - }); - } - - #[test] - fn on_runtime_is_noop_if_versions_are_not_correct() { - ExtBuilder::default().build().execute_with(|| { - // storage migration already executed (storage version is incremented already) - StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - - let hash = crate::migrations::utility::key_to_hash::(0); - let outcome = OutcomeReport::Categorical(42u16); - let now = >::block_number(); - let resolve_at: ::BlockNumber = now - .saturating_add(::AuthorityReportPeriod::get()); - let report = AuthorityReport { resolve_at, outcome }; - put_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, Some(report.clone())); - - AddFieldToAuthorityReport::::on_runtime_upgrade(); - - let actual = frame_support::migration::get_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) - .unwrap(); - assert_eq!(Some(report), actual); - }); - } +const AUTHORIZED: &[u8] = b"Authorized"; +const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; - fn set_up_chain() { - StorageVersion::new(AUTHORIZED_REQUIRED_STORAGE_VERSION).put::>(); - } -} +const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; +const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); @@ -320,7 +155,7 @@ mod tests_auto_resolution { }; use zeitgeist_primitives::types::{ Deadlines, MarketCreation, MarketDisputeMechanism, MarketId, MarketPeriod, MarketStatus, - OutcomeReport, Report, ScoringRule, + OutcomeReport, Report, ScoringRule, MarketType, }; use zrml_market_commons::Markets; @@ -497,384 +332,150 @@ mod tests_auto_resolution { } } -pub struct TransformScalarMarketsToFixedPoint(PhantomData); +pub struct AddFieldToAuthorityReport(PhantomData); -// Transform all scalar intervals by BASE, thereby turning every scalar position into a fixed point -// number with ten digits after the decimal point. This update should only be executed if the -// interpretation of metadata in changed in parallel. If that is the case, market description need -// not be updated. -impl - OnRuntimeUpgrade for TransformScalarMarketsToFixedPoint +// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. +impl OnRuntimeUpgrade + for AddFieldToAuthorityReport where ::MarketId: EncodeLike< <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId, >, - ::MarketId: - EncodeLike<<::MarketCommons as MarketCommonsPalletApi>::MarketId>, - ::MarketId: - EncodeLike<<::MarketCommons as MarketCommonsPalletApi>::MarketId>, { fn on_runtime_upgrade() -> Weight where T: Config, { - let mut total_weight = T::DbWeight::get().reads(4); + let mut total_weight = T::DbWeight::get().reads(1); let authorized_version = StorageVersion::get::>(); - let court_version = StorageVersion::get::>(); - let market_commons_version = StorageVersion::get::>(); - let prediction_markets_version = StorageVersion::get::>(); - if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION - || court_version != COURT_REQUIRED_STORAGE_VERSION - || market_commons_version != MARKET_COMMONS_REQUIRED_STORAGE_VERSION - || prediction_markets_version != PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION - { + if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION { log::info!( - "TransformScalarMarketsToFixedPoint: authorized version is {:?}, require {:?}; \ - court version is {:?}, require {:?}; market-commons version is {:?}, require \ - {:?}; prediction-markets version is {:?}, require {:?}", + "AddFieldToAuthorityReport: authorized version is {:?}, require {:?};", authorized_version, AUTHORIZED_REQUIRED_STORAGE_VERSION, - court_version, - COURT_REQUIRED_STORAGE_VERSION, - market_commons_version, - MARKET_COMMONS_REQUIRED_STORAGE_VERSION, - prediction_markets_version, - PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION, ); return total_weight; } - log::info!("TransformScalarMarketsToFixedPoint: Starting..."); + log::info!("AddFieldToAuthorityReport: Starting..."); - let mut new_scalar_markets: Vec<_> = vec![]; - for (market_id, mut market) in MarketCommonsPallet::::market_iter() { + let mut new_storage_map = Vec::new(); + let now = >::block_number(); + for (key, old_value) in + storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) + { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - if let MarketType::Scalar(range) = market.market_type { - let new_start = to_fixed_point(*range.start()); - let new_end = to_fixed_point(*range.end()); - market.market_type = MarketType::Scalar(new_start..=new_end); - - if let Some(mut report) = market.report { - if let OutcomeReport::Scalar(value) = report.outcome { - report.outcome = OutcomeReport::Scalar(to_fixed_point(value)); - } - market.report = Some(report); - } - if let Some(mut resolved_outcome) = market.resolved_outcome { - if let OutcomeReport::Scalar(value) = resolved_outcome { - resolved_outcome = OutcomeReport::Scalar(to_fixed_point(value)); - } - market.resolved_outcome = Some(resolved_outcome); - } - - let old_disputes = Disputes::::get(market_id); - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - let new_disputes = if old_disputes.is_empty() { - None - } else { - BoundedVec::try_from( - old_disputes - .into_iter() - .map(|mut dispute| { - if let OutcomeReport::Scalar(value) = dispute.outcome { - dispute.outcome = OutcomeReport::Scalar(to_fixed_point(value)); - }; - dispute - }) - .collect::>(), - ) - .ok() - }; - - let authorized_report = match AuthorizedOutcomeReports::::get(market_id) { - Some(mut outcome_report) => { - if let OutcomeReport::Scalar(value) = outcome_report.outcome { - outcome_report.outcome = OutcomeReport::Scalar(to_fixed_point(value)); - } - Some(outcome_report) - } - None => None, - }; - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - - let votes = Votes::::iter_prefix(market_id) - .filter_map(|(juror, (block_number, outcome_report))| { - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - match outcome_report { - OutcomeReport::Scalar(value) => Some(( - juror, - (block_number, OutcomeReport::Scalar(to_fixed_point(value))), - )), - _ => None, - } - }) - .collect::>(); - - new_scalar_markets.push(( - market_id, - market, - new_disputes, - authorized_report, - votes, - )); + if let Some(outcome) = old_value { + let resolve_at: T::BlockNumber = now + .saturating_add(::AuthorityReportPeriod::get()); + let new_value = AuthorityReport { resolve_at, outcome }; + new_storage_map.push((key, new_value)); } } - for (market_id, market, disputes, authorized_report, votes) in new_scalar_markets { - let _ = MarketCommonsPallet::::mutate_market(&market_id, |old_market| { - *old_market = market; - Ok(()) - }); + for (key, new_value) in new_storage_map { + put_storage_value::>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &key, + Some(new_value), + ); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - - if let Some(disputes_unwrapped) = disputes { - Disputes::::insert(market_id, disputes_unwrapped); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - } - - if let Some(outcome_report) = authorized_report { - AuthorizedOutcomeReports::::insert(market_id, outcome_report); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - } - - for (juror, vote) in votes { - Votes::::insert(market_id, juror, vote); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - } } StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - StorageVersion::new(COURT_NEXT_STORAGE_VERSION).put::>(); - StorageVersion::new(MARKET_COMMONS_NEXT_STORAGE_VERSION).put::>(); - StorageVersion::new(PREDICTION_MARKETS_NEXT_STORAGE_VERSION).put::>(); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(4)); - log::info!("TransformScalarMarketsToFixedPoint: Done!"); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::info!("AddFieldToAuthorityReport: Done!"); total_weight } #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - // Check that no saturation occurs. - for (market_id, market) in MarketCommonsPallet::::market_iter() { - if let MarketType::Scalar(range) = market.market_type { - assert!( - range.end().checked_mul(BASE).is_some(), - "TransformScalarMarketsToFixedPoint: Arithmetic overflow when transforming \ - market {:?}", - market_id, - ); - } - } Ok(()) } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - for (market_id, market) in MarketCommonsPallet::::market_iter() { - if let MarketType::Scalar(range) = market.market_type { - assert_ne!( - range.start(), - range.end(), - "TransformScalarMarketsToFixedPoint: Scalar range broken after transformation \ - of market {:?}", - market_id, - ); - } - } Ok(()) } } -fn to_fixed_point(value: u128) -> u128 { - value.saturating_mul(BASE) -} - #[cfg(test)] -mod tests { +mod tests_authorized { use super::*; - use crate::{ - mock::{ExtBuilder, Runtime}, - Disputes, MomentOf, - }; - use zeitgeist_primitives::types::{ - Deadlines, MarketCreation, MarketDispute, MarketDisputeMechanism, MarketId, MarketPeriod, - MarketStatus, OutcomeReport, Report, ScoringRule, - }; - use zrml_market_commons::Markets; - - type Market = zeitgeist_primitives::types::Market< - ::AccountId, - ::BlockNumber, - MomentOf, - >; - type MarketDisputeOf = MarketDispute< - ::AccountId, - ::BlockNumber, - >; + use crate::mock::{ExtBuilder, Runtime}; + use frame_support::Twox64Concat; + use zeitgeist_primitives::types::{MarketId, OutcomeReport}; #[test] fn on_runtime_upgrade_increments_the_storage_versions() { ExtBuilder::default().build().execute_with(|| { set_up_chain(); - TransformScalarMarketsToFixedPoint::::on_runtime_upgrade(); + AddFieldToAuthorityReport::::on_runtime_upgrade(); let authorized_version = StorageVersion::get::>(); - let court_version = StorageVersion::get::>(); - let market_commons_version = StorageVersion::get::>(); - let prediction_markets_version = StorageVersion::get::>(); assert_eq!(authorized_version, AUTHORIZED_NEXT_STORAGE_VERSION); - assert_eq!(court_version, COURT_NEXT_STORAGE_VERSION); - assert_eq!(market_commons_version, MARKET_COMMONS_NEXT_STORAGE_VERSION); - assert_eq!(prediction_markets_version, PREDICTION_MARKETS_NEXT_STORAGE_VERSION); }); } #[test] - fn on_runtime_upgrade_ignores_categorical_markets() { + fn on_runtime_sets_new_struct_with_resolve_at() { ExtBuilder::default().build().execute_with(|| { set_up_chain(); - let market_id: MarketId = 7; - let market = Market { - creator: 1, - creation: MarketCreation::Permissionless, - creator_fee: 2, - oracle: 3, - metadata: vec![4, 5], - market_type: MarketType::Categorical(14), - period: MarketPeriod::Block(6..7), - deadlines: Deadlines { grace_period: 8, oracle_duration: 9, dispute_duration: 10 }, - scoring_rule: ScoringRule::CPMM, - status: MarketStatus::Resolved, - report: Some(Report { at: 11, by: 12, outcome: OutcomeReport::Categorical(13) }), - resolved_outcome: Some(OutcomeReport::Categorical(13)), - dispute_mechanism: MarketDisputeMechanism::Court, - }; - Markets::::insert(market_id, market.clone()); - TransformScalarMarketsToFixedPoint::::on_runtime_upgrade(); - let market_after = Markets::::get(market_id); - assert_eq!(market, market_after.unwrap()); - }); - } - #[test] - fn on_runtime_transforms_scalar_markets_and_their_disputes() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); + >::set_block_number(10_000); - let market_id: MarketId = 7; - let market = Market { - creator: 1, - creation: MarketCreation::Permissionless, - creator_fee: 2, - oracle: 3, - metadata: vec![4, 5], - market_type: MarketType::Scalar(14..=15), - period: MarketPeriod::Block(6..7), - deadlines: Deadlines { grace_period: 8, oracle_duration: 9, dispute_duration: 10 }, - scoring_rule: ScoringRule::CPMM, - status: MarketStatus::Resolved, - report: Some(Report { at: 11, by: 12, outcome: OutcomeReport::Categorical(13) }), - resolved_outcome: Some(OutcomeReport::Categorical(13)), - dispute_mechanism: MarketDisputeMechanism::Court, - }; - Markets::::insert(market_id, market.clone()); - - let dispute = - MarketDisputeOf:: { at: 16, by: 17, outcome: OutcomeReport::Scalar(18) }; - Disputes::::insert( - market_id, - BoundedVec::try_from(vec![dispute.clone()]).unwrap(), + let hash = crate::migrations::utility::key_to_hash::(0); + let outcome = OutcomeReport::Categorical(42u16); + put_storage_value::>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &hash, + Some(outcome.clone()), ); - let report = AuthorityReport { resolve_at: 42, outcome: OutcomeReport::Scalar(19) }; - AuthorizedOutcomeReports::::insert(market_id, report); - - let juror = 20; - let block_number = 21; - Votes::::insert(market_id, juror, (block_number, OutcomeReport::Scalar(22))); - - TransformScalarMarketsToFixedPoint::::on_runtime_upgrade(); - - let mut market_expected = market; - market_expected.market_type = MarketType::Scalar(140_000_000_000..=150_000_000_000); - let market_after = Markets::::get(market_id).unwrap(); - assert_eq!(market_after, market_expected); - - let mut dispute_expected = dispute; - dispute_expected.outcome = OutcomeReport::Scalar(180_000_000_000); - let disputes_after = Disputes::::get(market_id); - assert_eq!(disputes_after.len(), 1); - assert_eq!(disputes_after[0], dispute_expected); + AddFieldToAuthorityReport::::on_runtime_upgrade(); - let authorized_report_after = - AuthorizedOutcomeReports::::get(market_id).unwrap(); - assert_eq!(authorized_report_after.outcome, OutcomeReport::Scalar(190_000_000_000)); + let now = >::block_number(); + let resolve_at: ::BlockNumber = now + .saturating_add(::AuthorityReportPeriod::get()); + let expected = Some(AuthorityReport { resolve_at, outcome }); - let vote_after = Votes::::get(market_id, juror).unwrap(); - assert_eq!(vote_after, (block_number, OutcomeReport::Scalar(220_000_000_000))); + let actual = frame_support::migration::get_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) + .unwrap(); + assert_eq!(expected, actual); }); } #[test] fn on_runtime_is_noop_if_versions_are_not_correct() { ExtBuilder::default().build().execute_with(|| { - // Don't set up chain to signal that storage is already up to date. - - let market_id: MarketId = 7; - let market = Market { - creator: 1, - creation: MarketCreation::Permissionless, - creator_fee: 2, - oracle: 3, - metadata: vec![4, 5], - market_type: MarketType::Scalar(14..=15), - period: MarketPeriod::Block(6..7), - deadlines: Deadlines { grace_period: 8, oracle_duration: 9, dispute_duration: 10 }, - scoring_rule: ScoringRule::CPMM, - status: MarketStatus::Resolved, - report: Some(Report { at: 11, by: 12, outcome: OutcomeReport::Categorical(13) }), - resolved_outcome: Some(OutcomeReport::Categorical(13)), - dispute_mechanism: MarketDisputeMechanism::Court, - }; - Markets::::insert(market_id, market.clone()); - - let dispute = - MarketDisputeOf:: { at: 16, by: 17, outcome: OutcomeReport::Scalar(18) }; - Disputes::::insert( - market_id, - BoundedVec::try_from(vec![dispute.clone()]).unwrap(), - ); - - let report = AuthorityReport { resolve_at: 42, outcome: OutcomeReport::Scalar(19) }; - AuthorizedOutcomeReports::::insert(market_id, report); - - let juror = 20; - let vote = (21, OutcomeReport::Scalar(22)); - Votes::::insert(market_id, juror, vote.clone()); - - TransformScalarMarketsToFixedPoint::::on_runtime_upgrade(); - - let market_after = Markets::::get(market_id).unwrap(); - assert_eq!(market_after, market); + // storage migration already executed (storage version is incremented already) + StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - let disputes_after = Disputes::::get(market_id); - assert_eq!(disputes_after.len(), 1); - assert_eq!(disputes_after[0], dispute); + let hash = crate::migrations::utility::key_to_hash::(0); + let outcome = OutcomeReport::Categorical(42u16); + let now = >::block_number(); + let resolve_at: ::BlockNumber = now + .saturating_add(::AuthorityReportPeriod::get()); + let report = AuthorityReport { resolve_at, outcome }; + put_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, Some(report.clone())); - let authorized_report_after = - AuthorizedOutcomeReports::::get(market_id).unwrap(); - assert_eq!(authorized_report_after.outcome, OutcomeReport::Scalar(19)); + AddFieldToAuthorityReport::::on_runtime_upgrade(); - let vote_after = Votes::::get(market_id, juror).unwrap(); - assert_eq!(vote_after, vote); + let actual = frame_support::migration::get_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) + .unwrap(); + assert_eq!(Some(report), actual); }); } fn set_up_chain() { StorageVersion::new(AUTHORIZED_REQUIRED_STORAGE_VERSION).put::>(); - StorageVersion::new(COURT_REQUIRED_STORAGE_VERSION).put::>(); - StorageVersion::new(MARKET_COMMONS_REQUIRED_STORAGE_VERSION) - .put::>(); - StorageVersion::new(PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION).put::>(); } } From fedd8195985b7c2af04dbcff388f5e840d6c485d Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 25 Nov 2022 14:17:32 +0100 Subject: [PATCH 21/93] cargo fmt --- zrml/prediction-markets/src/migrations.rs | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index d663121c6..3adda3b0f 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -16,7 +16,7 @@ // along with Zeitgeist. If not, see . use crate::{CacheSize, Config, MarketIdOf, Pallet}; -use alloc::{vec::Vec}; +use alloc::vec::Vec; use frame_support::{ dispatch::Weight, log, @@ -27,11 +27,9 @@ use frame_support::{ }; use parity_scale_codec::EncodeLike; use sp_runtime::traits::{One, Saturating}; -use zeitgeist_primitives::{ - types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}, -}; -use zrml_authorized::{Pallet as AuthorizedPallet}; -use zrml_market_commons::{MarketCommonsPalletApi}; +use zeitgeist_primitives::types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}; +use zrml_authorized::Pallet as AuthorizedPallet; +use zrml_market_commons::MarketCommonsPalletApi; const PREDICTION_MARKETS: &[u8] = b"PredictionMarkets"; const MARKET_IDS_PER_DISPUTE_BLOCK: &[u8] = b"MarketIdsPerDisputeBlock"; @@ -155,7 +153,7 @@ mod tests_auto_resolution { }; use zeitgeist_primitives::types::{ Deadlines, MarketCreation, MarketDisputeMechanism, MarketId, MarketPeriod, MarketStatus, - OutcomeReport, Report, ScoringRule, MarketType, + MarketType, OutcomeReport, Report, ScoringRule, }; use zrml_market_commons::Markets; From 818c68a8435e57ca5af5de88a59e81143f4335a0 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 25 Nov 2022 15:03:30 +0100 Subject: [PATCH 22/93] modify storage versions to test try-runtime --- zrml/prediction-markets/src/migrations.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 3adda3b0f..908bd793e 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -34,14 +34,16 @@ use zrml_market_commons::MarketCommonsPalletApi; const PREDICTION_MARKETS: &[u8] = b"PredictionMarkets"; const MARKET_IDS_PER_DISPUTE_BLOCK: &[u8] = b"MarketIdsPerDisputeBlock"; -const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 6; -const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 7; +// TODO increase storage versions here, when last migration was executed +const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 5; +const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 6; const AUTHORIZED: &[u8] = b"Authorized"; const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; -const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; -const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; +// TODO increase storage versions here, when last migration was executed +const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 1; +const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 2; pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); From 4a4f2d442434a2851bc85beaf49f9046025adbbc Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 5 Dec 2022 09:48:23 +0100 Subject: [PATCH 23/93] edit doc comment --- primitives/src/traits/dispute_api.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 36274c0c7..c49f2cc07 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -53,7 +53,7 @@ pub trait DisputeApi { ) -> Result, DispatchError>; /// Query the future resolution block of a disputed market. - /// Fails if the market dispute mechanism does not belong to the actual dispute mechanism. + /// **May** assume that `market.dispute_mechanism` refers to the calling dispute API. /// /// # Returns /// @@ -65,7 +65,7 @@ pub trait DisputeApi { ) -> Result, DispatchError>; /// Query if the dispute mechanism failed for a dispute market. - /// Fails if the market dispute mechanism does not belong to the actual dispute mechanism. + /// **May** assume that `market.dispute_mechanism` refers to the calling dispute API. /// /// # Returns /// From 722d29c868e2ba9211097cb84bbd506adef7d2d5 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 5 Dec 2022 10:33:52 +0100 Subject: [PATCH 24/93] simplify doc comment --- primitives/src/traits/dispute_api.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index c49f2cc07..021c26366 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -97,11 +97,6 @@ pub trait DisputeResolutionApi { ) -> Result; /// Add a future block resolution of a disputed market. - /// Fails in case of a storage overflow. - /// - /// # Returns - /// - /// Returns Ok if the market id was added succesfully. fn add_auto_resolve( market_id: &Self::MarketId, resolution: Self::BlockNumber, From 7281007c0d260ff50af8dbdd4fa0af5af7b44f87 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 5 Dec 2022 12:34:46 +0100 Subject: [PATCH 25/93] update benchmark authorize outcome --- primitives/src/traits/dispute_api.rs | 12 +++++++-- zrml/authorized/src/benchmarks.rs | 38 +++++++++++++++++++++++++--- zrml/authorized/src/lib.rs | 29 +++++++++++++-------- zrml/authorized/src/mock.rs | 8 +++--- zrml/authorized/src/weights.rs | 23 ++++++++++------- zrml/court/src/mock.rs | 8 +++--- zrml/prediction-markets/src/lib.rs | 21 +++++++++------ zrml/simple-disputes/src/mock.rs | 8 +++--- 8 files changed, 105 insertions(+), 42 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 021c26366..3647ff21f 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -97,11 +97,19 @@ pub trait DisputeResolutionApi { ) -> Result; /// Add a future block resolution of a disputed market. + /// + /// # Returns + /// + /// Returns the number of elements in the storage structure. fn add_auto_resolve( market_id: &Self::MarketId, resolution: Self::BlockNumber, - ) -> DispatchResult; + ) -> Result; /// Remove a future block resolution of a disputed market. - fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber); + /// + /// # Returns + /// + /// Returns the number of elements in the storage structure. + fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber) -> u32; } diff --git a/zrml/authorized/src/benchmarks.rs b/zrml/authorized/src/benchmarks.rs index 9fe9cbe59..844fdb1c5 100644 --- a/zrml/authorized/src/benchmarks.rs +++ b/zrml/authorized/src/benchmarks.rs @@ -23,18 +23,48 @@ #[cfg(test)] use crate::Pallet as Authorized; -use crate::{market_mock, Call, Config, Pallet}; +use crate::{market_mock, AuthorizedOutcomeReports, Call, Config, Pallet}; use frame_benchmarking::{benchmarks, impl_benchmark_test_suite}; -use frame_support::{dispatch::UnfilteredDispatchable, traits::EnsureOrigin}; -use zeitgeist_primitives::types::OutcomeReport; +use frame_support::{ + dispatch::UnfilteredDispatchable, + traits::{EnsureOrigin, Get}, +}; +use sp_runtime::traits::Saturating; +use zeitgeist_primitives::{ + traits::DisputeResolutionApi, + types::{AuthorityReport, OutcomeReport}, +}; use zrml_market_commons::MarketCommonsPalletApi; benchmarks! { authorize_market_outcome { + let m in 1..63; + let d in 1..63; + let origin = T::AuthorizedDisputeResolutionOrigin::successful_origin(); + let market_id = 0u32.into(); let market = market_mock::(); T::MarketCommonsAuthorized::push_market(market).unwrap(); - let call = Call::::authorize_market_outcome { market_id: 0_u32.into(), outcome: OutcomeReport::Scalar(1) }; + let call = Call::::authorize_market_outcome { + market_id, + outcome: OutcomeReport::Scalar(1), + }; + + let now = frame_system::Pallet::::block_number(); + + let resolve_at = now.saturating_add(T::CorrectionPeriod::get() - 1u32.into()); + let report = AuthorityReport { resolve_at, outcome: OutcomeReport::Scalar(0) }; + for _ in 1..=m { + let id = T::MarketCommonsAuthorized::push_market(market_mock::()).unwrap(); + T::DisputeResolution::add_auto_resolve(&id, resolve_at).unwrap(); + } + AuthorizedOutcomeReports::::insert(market_id, report); + + let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); + for _ in 1..=d { + let id = T::MarketCommonsAuthorized::push_market(market_mock::()).unwrap(); + T::DisputeResolution::add_auto_resolve(&id, correction_period_ends_at).unwrap(); + } }: { call.dispatch_bypass_filter(origin)? } } diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 27f2df92f..8cc27f4fc 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -35,9 +35,9 @@ mod pallet { use crate::{weights::WeightInfoZeitgeist, AuthorizedPalletApi}; use core::marker::PhantomData; use frame_support::{ - dispatch::DispatchResult, + dispatch::{DispatchResult, DispatchResultWithPostInfo}, ensure, - pallet_prelude::{EnsureOrigin, OptionQuery, StorageMap}, + pallet_prelude::{ConstU32, EnsureOrigin, OptionQuery, StorageMap}, traits::{Currency, Get, Hooks, IsType, StorageVersion}, PalletId, Twox64Concat, }; @@ -64,32 +64,39 @@ mod pallet { pub(crate) type MomentOf = <::MarketCommonsAuthorized as MarketCommonsPalletApi>::Moment; + pub type CacheSize = ConstU32<64>; + #[pallet::call] impl Pallet { - // TODO update benchmark /// Overwrites already provided outcomes for the same market and account. #[frame_support::transactional] - #[pallet::weight(T::WeightInfo::authorize_market_outcome())] + #[pallet::weight(T::WeightInfo::authorize_market_outcome( + CacheSize::get(), + CacheSize::get() + ))] pub fn authorize_market_outcome( origin: OriginFor, market_id: MarketIdOf, outcome: OutcomeReport, - ) -> DispatchResult { + ) -> DispatchResultWithPostInfo { T::AuthorizedDisputeResolutionOrigin::ensure_origin(origin)?; let market = T::MarketCommonsAuthorized::market(&market_id)?; ensure!(market.status == MarketStatus::Disputed, Error::::MarketIsNotDisputed); ensure!(market.matches_outcome_report(&outcome), Error::::OutcomeMismatch); match market.dispute_mechanism { MarketDisputeMechanism::Authorized => { - Self::remove_auto_resolve(&market_id); + let ids_len_1 = Self::remove_auto_resolve(&market_id); let now = frame_system::Pallet::::block_number(); let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); - T::DisputeResolution::add_auto_resolve(&market_id, correction_period_ends_at)?; + let ids_len_2 = T::DisputeResolution::add_auto_resolve( + &market_id, + correction_period_ends_at, + )?; let report = AuthorityReport { resolve_at: correction_period_ends_at, outcome }; AuthorizedOutcomeReports::::insert(market_id, report); - Ok(()) + Ok(Some(T::WeightInfo::authorize_market_outcome(ids_len_1, ids_len_2)).into()) } _ => Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()), } @@ -169,9 +176,11 @@ mod pallet { AuthorizedOutcomeReports::::get(market_id).map(|report| report.resolve_at) } - fn remove_auto_resolve(market_id: &MarketIdOf) { + fn remove_auto_resolve(market_id: &MarketIdOf) -> u32 { if let Some(resolve_at) = Self::get_auto_resolve(market_id) { - T::DisputeResolution::remove_auto_resolve(market_id, resolve_at); + T::DisputeResolution::remove_auto_resolve(market_id, resolve_at) + } else { + 0u32 } } } diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index c68c31ac0..d60104873 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -80,11 +80,13 @@ impl DisputeResolutionApi for NoopResolution { fn add_auto_resolve( _market_id: &Self::MarketId, _resolution: Self::BlockNumber, - ) -> frame_support::pallet_prelude::DispatchResult { - Ok(()) + ) -> Result { + Ok(0u32) } - fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) {} + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) -> u32 { + 0u32 + } } impl crate::Config for Runtime { diff --git a/zrml/authorized/src/weights.rs b/zrml/authorized/src/weights.rs index 4729346fa..000326fe4 100644 --- a/zrml/authorized/src/weights.rs +++ b/zrml/authorized/src/weights.rs @@ -18,11 +18,11 @@ //! Autogenerated weights for zrml_authorized //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-10-17, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2022-12-05, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/zeitgeist +// ./target/release/zeitgeist // benchmark // pallet // --chain=dev @@ -33,8 +33,8 @@ // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --template=./misc/weight_template.hbs // --output=./zrml/authorized/src/weights.rs +// --template=./misc/weight_template.hbs #![allow(unused_parens)] #![allow(unused_imports)] @@ -45,17 +45,22 @@ use frame_support::{traits::Get, weights::Weight}; /// Trait containing the required functions for weight retrival within /// zrml_authorized (automatically generated) pub trait WeightInfoZeitgeist { - fn authorize_market_outcome() -> Weight; + fn authorize_market_outcome(m: u32, d: u32) -> Weight; } /// Weight functions for zrml_authorized (automatically generated) pub struct WeightInfo(PhantomData); impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons Markets (r:1 w:0) - // Storage: Authorized AuthorizedOutcomeReports (r:0 w:1) - fn authorize_market_outcome() -> Weight { - (13_450_000 as Weight) - .saturating_add(T::DbWeight::get().reads(1 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) + // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:2 w:2) + fn authorize_market_outcome(m: u32, d: u32) -> Weight { + (22_684_000 as Weight) + // Standard Error: 0 + .saturating_add((26_000 as Weight).saturating_mul(m as Weight)) + // Standard Error: 0 + .saturating_add((13_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) } } diff --git a/zrml/court/src/mock.rs b/zrml/court/src/mock.rs index b876fd88e..717f6ceb8 100644 --- a/zrml/court/src/mock.rs +++ b/zrml/court/src/mock.rs @@ -81,11 +81,13 @@ impl DisputeResolutionApi for NoopResolution { fn add_auto_resolve( _market_id: &Self::MarketId, _resolution: Self::BlockNumber, - ) -> frame_support::pallet_prelude::DispatchResult { - Ok(()) + ) -> Result { + Ok(0u32) } - fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) {} + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) -> u32 { + 0u32 + } } impl crate::Config for Runtime { diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index f585399b9..c199970b8 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -2917,17 +2917,22 @@ mod pallet { fn add_auto_resolve( market_id: &Self::MarketId, resolution: Self::BlockNumber, - ) -> DispatchResult { - >::try_mutate(resolution, |ids| { - ids.try_push(*market_id).map_err(|_| >::StorageOverflow) - })?; - Ok(()) + ) -> Result { + let ids_len = >::try_mutate( + resolution, + |ids| -> Result { + ids.try_push(*market_id).map_err(|_| >::StorageOverflow)?; + Ok(ids.len() as u32) + }, + )?; + Ok(ids_len) } - fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber) { - MarketIdsPerDisputeBlock::::mutate(resolution, |ids| { + fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber) -> u32 { + MarketIdsPerDisputeBlock::::mutate(resolution, |ids| -> u32 { remove_item::, _>(ids, market_id); - }); + ids.len() as u32 + }) } } } diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index 65ad05566..dfb45e580 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -68,11 +68,13 @@ impl DisputeResolutionApi for NoopResolution { fn add_auto_resolve( _market_id: &Self::MarketId, _resolution: Self::BlockNumber, - ) -> frame_support::pallet_prelude::DispatchResult { - Ok(()) + ) -> Result { + Ok(0u32) } - fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) {} + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) -> u32 { + 0u32 + } } impl crate::Config for Runtime { From 7059171209b710898ccddca3ba1826159decf112 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 5 Dec 2022 12:38:03 +0100 Subject: [PATCH 26/93] avoid indentation --- zrml/authorized/src/lib.rs | 32 +++++++++++++++----------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 8cc27f4fc..4e5256297 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -83,23 +83,21 @@ mod pallet { let market = T::MarketCommonsAuthorized::market(&market_id)?; ensure!(market.status == MarketStatus::Disputed, Error::::MarketIsNotDisputed); ensure!(market.matches_outcome_report(&outcome), Error::::OutcomeMismatch); - match market.dispute_mechanism { - MarketDisputeMechanism::Authorized => { - let ids_len_1 = Self::remove_auto_resolve(&market_id); - let now = frame_system::Pallet::::block_number(); - let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); - let ids_len_2 = T::DisputeResolution::add_auto_resolve( - &market_id, - correction_period_ends_at, - )?; - - let report = AuthorityReport { resolve_at: correction_period_ends_at, outcome }; - AuthorizedOutcomeReports::::insert(market_id, report); - - Ok(Some(T::WeightInfo::authorize_market_outcome(ids_len_1, ids_len_2)).into()) - } - _ => Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()), - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Authorized, + Error::::MarketDoesNotHaveDisputeMechanismAuthorized + ); + + let ids_len_1 = Self::remove_auto_resolve(&market_id); + let now = frame_system::Pallet::::block_number(); + let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); + let ids_len_2 = + T::DisputeResolution::add_auto_resolve(&market_id, correction_period_ends_at)?; + + let report = AuthorityReport { resolve_at: correction_period_ends_at, outcome }; + AuthorizedOutcomeReports::::insert(market_id, report); + + Ok(Some(T::WeightInfo::authorize_market_outcome(ids_len_1, ids_len_2)).into()) } } From 39b2bbf4a4b9c5731022ec1f21423f9f8d9445e4 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 5 Dec 2022 13:11:57 +0100 Subject: [PATCH 27/93] rename AuthorityReportPeriod to ReportPeriod --- primitives/src/constants/mock.rs | 2 +- runtime/battery-station/src/parameters.rs | 2 +- runtime/common/src/lib.rs | 2 +- runtime/zeitgeist/src/parameters.rs | 2 +- zrml/authorized/src/lib.rs | 4 ++-- zrml/authorized/src/mock.rs | 4 ++-- zrml/prediction-markets/src/benchmarks.rs | 8 ++++---- zrml/prediction-markets/src/migrations.rs | 10 +++++----- zrml/prediction-markets/src/mock.rs | 4 ++-- zrml/prediction-markets/src/tests.rs | 6 +++--- 10 files changed, 22 insertions(+), 22 deletions(-) diff --git a/primitives/src/constants/mock.rs b/primitives/src/constants/mock.rs index b75885074..f6f30d0d9 100644 --- a/primitives/src/constants/mock.rs +++ b/primitives/src/constants/mock.rs @@ -10,7 +10,7 @@ use orml_traits::parameter_type_with_key; // Authorized parameter_types! { - pub const AuthorityReportPeriod: BlockNumber = 10; + pub const ReportPeriod: BlockNumber = 10; pub const AuthorizedPalletId: PalletId = PalletId(*b"zge/atzd"); pub const CorrectionPeriod: BlockNumber = 4; } diff --git a/runtime/battery-station/src/parameters.rs b/runtime/battery-station/src/parameters.rs index d6de551a5..f4b655939 100644 --- a/runtime/battery-station/src/parameters.rs +++ b/runtime/battery-station/src/parameters.rs @@ -50,7 +50,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized - pub const AuthorityReportPeriod: BlockNumber = 6 * BLOCKS_PER_DAY; + pub const ReportPeriod: BlockNumber = 6 * BLOCKS_PER_DAY; pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; pub const CorrectionPeriod: BlockNumber = 3 * BLOCKS_PER_HOUR; diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index f794d89a0..efe3f216c 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -873,7 +873,7 @@ macro_rules! impl_config_traits { impl parachain_info::Config for Runtime {} impl zrml_authorized::Config for Runtime { - type AuthorityReportPeriod = AuthorityReportPeriod; + type ReportPeriod = ReportPeriod; type AuthorizedDisputeResolutionOrigin = EnsureRootOrTwoThirdsAdvisoryCommittee; type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = zrml_prediction_markets::Pallet; diff --git a/runtime/zeitgeist/src/parameters.rs b/runtime/zeitgeist/src/parameters.rs index 9b9c08e1e..236980e34 100644 --- a/runtime/zeitgeist/src/parameters.rs +++ b/runtime/zeitgeist/src/parameters.rs @@ -50,7 +50,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized - pub const AuthorityReportPeriod: BlockNumber = 6 * BLOCKS_PER_DAY; + pub const ReportPeriod: BlockNumber = 6 * BLOCKS_PER_DAY; pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; pub const CorrectionPeriod: BlockNumber = 6 * BLOCKS_PER_HOUR; diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 4e5256297..a00f89ea9 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -105,7 +105,7 @@ mod pallet { pub trait Config: frame_system::Config { /// The period in which the authority has to report. #[pallet::constant] - type AuthorityReportPeriod: Get; + type ReportPeriod: Get; /// Event type Event: From> + IsType<::Event>; @@ -246,7 +246,7 @@ mod pallet { let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); let report = market.report.as_ref().ok_or(Error::::MarketIsNotReported)?; let now = frame_system::Pallet::::block_number(); - let is_expired = report.at.saturating_add(T::AuthorityReportPeriod::get()) < now; + let is_expired = report.at.saturating_add(T::ReportPeriod::get()) < now; Ok(is_unreported && is_expired) } else { Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index d60104873..76fd2be71 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -28,7 +28,7 @@ use sp_runtime::{ }; use zeitgeist_primitives::{ constants::mock::{ - AuthorityReportPeriod, AuthorizedPalletId, BlockHashCount, CorrectionPeriod, MaxReserves, + ReportPeriod, AuthorizedPalletId, BlockHashCount, CorrectionPeriod, MaxReserves, MinimumPeriod, PmPalletId, BASE, }, traits::DisputeResolutionApi, @@ -90,7 +90,7 @@ impl DisputeResolutionApi for NoopResolution { } impl crate::Config for Runtime { - type AuthorityReportPeriod = AuthorityReportPeriod; + type ReportPeriod = ReportPeriod; type Event = (); type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = NoopResolution; diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index a7a6bc696..2d5e70d7b 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -872,9 +872,9 @@ benchmarks! { Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; } - let authority_report_period = ::AuthorityReportPeriod::get(); + let authority_report_period = ::ReportPeriod::get(); let now = >::block_number(); - // authorized mdm fails after the AuthorityReportPeriod + // authorized mdm fails after the ReportPeriod >::set_block_number( now + authority_report_period.saturated_into() + 1u64.saturated_into() ); @@ -913,9 +913,9 @@ benchmarks! { Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; } - let authority_report_period = ::AuthorityReportPeriod::get(); + let authority_report_period = ::ReportPeriod::get(); let now = >::block_number(); - // authorized mdm fails after the AuthorityReportPeriod + // authorized mdm fails after the ReportPeriod >::set_block_number( now + authority_report_period.saturated_into() + 1u64.saturated_into() ); diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 908bd793e..8989515fc 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -113,7 +113,7 @@ where let now = >::block_number(); for id in authorized_ids { let mut resolve_at: T::BlockNumber = - now.saturating_add(::AuthorityReportPeriod::get()); + now.saturating_add(::ReportPeriod::get()); let mut ids = crate::MarketIdsPerDisputeBlock::::get(resolve_at); total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); @@ -192,7 +192,7 @@ mod tests_auto_resolution { ); let resolve_at = now - .saturating_add(::AuthorityReportPeriod::get()); + .saturating_add(::ReportPeriod::get()); let full_ids: Vec = (MarketId::from(1u64)..=MarketId::from(64u64)).collect(); @@ -367,7 +367,7 @@ where if let Some(outcome) = old_value { let resolve_at: T::BlockNumber = now - .saturating_add(::AuthorityReportPeriod::get()); + .saturating_add(::ReportPeriod::get()); let new_value = AuthorityReport { resolve_at, outcome }; new_storage_map.push((key, new_value)); } @@ -437,7 +437,7 @@ mod tests_authorized { let now = >::block_number(); let resolve_at: ::BlockNumber = now - .saturating_add(::AuthorityReportPeriod::get()); + .saturating_add(::ReportPeriod::get()); let expected = Some(AuthorityReport { resolve_at, outcome }); let actual = frame_support::migration::get_storage_value::< @@ -458,7 +458,7 @@ mod tests_authorized { let outcome = OutcomeReport::Categorical(42u16); let now = >::block_number(); let resolve_at: ::BlockNumber = now - .saturating_add(::AuthorityReportPeriod::get()); + .saturating_add(::ReportPeriod::get()); let report = AuthorityReport { resolve_at, outcome }; put_storage_value::< Option::BlockNumber>>, diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 99a9305bd..7b0012e15 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -35,7 +35,7 @@ use sp_runtime::{ use substrate_fixed::{types::extra::U33, FixedI128, FixedU128}; use zeitgeist_primitives::{ constants::mock::{ - AuthorityReportPeriod, AuthorizedPalletId, BalanceFractionalDecimals, BlockHashCount, + ReportPeriod, AuthorizedPalletId, BalanceFractionalDecimals, BlockHashCount, CorrectionPeriod, CourtCaseDuration, CourtPalletId, DisputeFactor, ExistentialDeposit, ExistentialDeposits, ExitFee, GetNativeCurrencyId, LiquidityMiningPalletId, MaxApprovals, MaxAssets, MaxCategories, MaxDisputeDuration, MaxDisputes, MaxEditReasonLen, @@ -255,7 +255,7 @@ ord_parameter_types! { } impl zrml_authorized::Config for Runtime { - type AuthorityReportPeriod = AuthorityReportPeriod; + type ReportPeriod = ReportPeriod; type AuthorizedDisputeResolutionOrigin = EnsureSignedBy; type CorrectionPeriod = CorrectionPeriod; diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index c18be4670..16adc593c 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2340,7 +2340,7 @@ fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { let disputes = crate::Disputes::::get(0); assert_eq!(disputes.len(), 3); - run_blocks(::AuthorityReportPeriod::get() + 1); + run_blocks(::ReportPeriod::get() + 1); assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), 0)); let market_after = MarketCommons::market(&0).unwrap(); @@ -3229,14 +3229,14 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { let charlie_reserved = Balances::reserved_balance(&CHARLIE); assert_eq!(charlie_reserved, DisputeBond::get()); - run_blocks(::AuthorityReportPeriod::get()); + run_blocks(::ReportPeriod::get()); assert_noop!( PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id), Error::::DisputeMechanismNotFailed ); run_blocks(1); - // AuthorityReportPeriod is now over + // ReportPeriod is now over assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id)); let market_after = MarketCommons::market(&market_id).unwrap(); From 04fce1bbe872e4ec8e8f71af7dc01e51afa87e09 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 5 Dec 2022 13:48:52 +0100 Subject: [PATCH 28/93] use ensure --- zrml/authorized/src/lib.rs | 58 +++++++++++------------ zrml/authorized/src/mock.rs | 4 +- zrml/court/src/lib.rs | 30 +++++++----- zrml/prediction-markets/src/migrations.rs | 12 ++--- zrml/prediction-markets/src/mock.rs | 19 ++++---- zrml/simple-disputes/src/lib.rs | 33 +++++++------ 6 files changed, 82 insertions(+), 74 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index a00f89ea9..ee38c132b 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -199,14 +199,14 @@ mod pallet { market_id: &Self::MarketId, market: &Market, ) -> DispatchResult { - if let MarketDisputeMechanism::Authorized = market.dispute_mechanism { - if AuthorizedOutcomeReports::::get(market_id).is_some() { - return Err(Error::::AuthorityAlreadyReported.into()); - } - Ok(()) - } else { - Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Authorized, + Error::::MarketDoesNotHaveDisputeMechanismAuthorized + ); + if AuthorizedOutcomeReports::::get(market_id).is_some() { + return Err(Error::::AuthorityAlreadyReported.into()); } + Ok(()) } fn on_resolution( @@ -214,15 +214,15 @@ mod pallet { market_id: &Self::MarketId, market: &Market>, ) -> Result, DispatchError> { - if let MarketDisputeMechanism::Authorized = market.dispute_mechanism { - let result = AuthorizedOutcomeReports::::get(market_id); - if result.is_some() { - AuthorizedOutcomeReports::::remove(market_id); - } - Ok(result.map(|report| report.outcome)) - } else { - Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Authorized, + Error::::MarketDoesNotHaveDisputeMechanismAuthorized + ); + let result = AuthorizedOutcomeReports::::get(market_id); + if result.is_some() { + AuthorizedOutcomeReports::::remove(market_id); } + Ok(result.map(|report| report.outcome)) } fn get_auto_resolve( @@ -230,11 +230,11 @@ mod pallet { market_id: &Self::MarketId, market: &Market>, ) -> Result, DispatchError> { - if let MarketDisputeMechanism::Authorized = market.dispute_mechanism { - Ok(Self::get_auto_resolve(market_id)) - } else { - Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Authorized, + Error::::MarketDoesNotHaveDisputeMechanismAuthorized + ); + Ok(Self::get_auto_resolve(market_id)) } fn is_fail( @@ -242,15 +242,15 @@ mod pallet { market_id: &Self::MarketId, market: &Market>, ) -> Result { - if let MarketDisputeMechanism::Authorized = market.dispute_mechanism { - let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); - let report = market.report.as_ref().ok_or(Error::::MarketIsNotReported)?; - let now = frame_system::Pallet::::block_number(); - let is_expired = report.at.saturating_add(T::ReportPeriod::get()) < now; - Ok(is_unreported && is_expired) - } else { - Err(Error::::MarketDoesNotHaveDisputeMechanismAuthorized.into()) - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Authorized, + Error::::MarketDoesNotHaveDisputeMechanismAuthorized + ); + let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); + let report = market.report.as_ref().ok_or(Error::::MarketIsNotReported)?; + let now = frame_system::Pallet::::block_number(); + let is_expired = report.at.saturating_add(T::ReportPeriod::get()) < now; + Ok(is_unreported && is_expired) } } diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 76fd2be71..c3d2f08ae 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -28,8 +28,8 @@ use sp_runtime::{ }; use zeitgeist_primitives::{ constants::mock::{ - ReportPeriod, AuthorizedPalletId, BlockHashCount, CorrectionPeriod, MaxReserves, - MinimumPeriod, PmPalletId, BASE, + AuthorizedPalletId, BlockHashCount, CorrectionPeriod, MaxReserves, MinimumPeriod, + PmPalletId, ReportPeriod, BASE, }, traits::DisputeResolutionApi, types::{ diff --git a/zrml/court/src/lib.rs b/zrml/court/src/lib.rs index 8943eabbd..152b9fb71 100644 --- a/zrml/court/src/lib.rs +++ b/zrml/court/src/lib.rs @@ -50,6 +50,7 @@ mod pallet { use core::marker::PhantomData; use frame_support::{ dispatch::DispatchResult, + ensure, pallet_prelude::{CountedStorageMap, StorageDoubleMap, StorageValue, ValueQuery}, traits::{ BalanceStatus, Currency, Get, Hooks, IsType, NamedReservableCurrency, Randomness, @@ -507,9 +508,10 @@ mod pallet { market_id: &Self::MarketId, market: &Market, ) -> DispatchResult { - if market.dispute_mechanism != MarketDisputeMechanism::Court { - return Err(Error::::MarketDoesNotHaveCourtMechanism.into()); - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Court, + Error::::MarketDoesNotHaveCourtMechanism + ); let jurors: Vec<_> = Jurors::::iter().collect(); let necessary_jurors_num = Self::necessary_jurors_num(disputes); let mut rng = Self::rng(); @@ -531,9 +533,10 @@ mod pallet { market_id: &Self::MarketId, market: &Market>, ) -> Result, DispatchError> { - if market.dispute_mechanism != MarketDisputeMechanism::Court { - return Err(Error::::MarketDoesNotHaveCourtMechanism.into()); - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Court, + Error::::MarketDoesNotHaveCourtMechanism + ); let votes: Vec<_> = Votes::::iter_prefix(market_id).collect(); let requested_jurors: Vec<_> = RequestedJurors::::iter_prefix(market_id) .map(|(juror_id, max_allowed_block)| { @@ -559,10 +562,10 @@ mod pallet { _: &Self::MarketId, market: &Market>, ) -> Result, DispatchError> { - if market.dispute_mechanism != MarketDisputeMechanism::Court { - return Err(Error::::MarketDoesNotHaveCourtMechanism.into()); - } - + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Court, + Error::::MarketDoesNotHaveCourtMechanism + ); Ok(None) } @@ -571,9 +574,10 @@ mod pallet { _: &Self::MarketId, market: &Market>, ) -> Result { - if market.dispute_mechanism != MarketDisputeMechanism::Court { - return Err(Error::::MarketDoesNotHaveCourtMechanism.into()); - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::Court, + Error::::MarketDoesNotHaveCourtMechanism + ); // TODO when does court fail? Ok(false) } diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 8989515fc..226ff323c 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -191,8 +191,8 @@ mod tests_auto_resolution { BoundedVec::try_from(vec![market_id]).unwrap(), ); - let resolve_at = now - .saturating_add(::ReportPeriod::get()); + let resolve_at = + now.saturating_add(::ReportPeriod::get()); let full_ids: Vec = (MarketId::from(1u64)..=MarketId::from(64u64)).collect(); @@ -436,8 +436,8 @@ mod tests_authorized { AddFieldToAuthorityReport::::on_runtime_upgrade(); let now = >::block_number(); - let resolve_at: ::BlockNumber = now - .saturating_add(::ReportPeriod::get()); + let resolve_at: ::BlockNumber = + now.saturating_add(::ReportPeriod::get()); let expected = Some(AuthorityReport { resolve_at, outcome }); let actual = frame_support::migration::get_storage_value::< @@ -457,8 +457,8 @@ mod tests_authorized { let hash = crate::migrations::utility::key_to_hash::(0); let outcome = OutcomeReport::Categorical(42u16); let now = >::block_number(); - let resolve_at: ::BlockNumber = now - .saturating_add(::ReportPeriod::get()); + let resolve_at: ::BlockNumber = + now.saturating_add(::ReportPeriod::get()); let report = AuthorityReport { resolve_at, outcome }; put_storage_value::< Option::BlockNumber>>, diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 7b0012e15..90dbb8672 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -35,15 +35,16 @@ use sp_runtime::{ use substrate_fixed::{types::extra::U33, FixedI128, FixedU128}; use zeitgeist_primitives::{ constants::mock::{ - ReportPeriod, AuthorizedPalletId, BalanceFractionalDecimals, BlockHashCount, - CorrectionPeriod, CourtCaseDuration, CourtPalletId, DisputeFactor, ExistentialDeposit, - ExistentialDeposits, ExitFee, GetNativeCurrencyId, LiquidityMiningPalletId, MaxApprovals, - MaxAssets, MaxCategories, MaxDisputeDuration, MaxDisputes, MaxEditReasonLen, - MaxGracePeriod, MaxInRatio, MaxMarketPeriod, MaxOracleDuration, MaxOutRatio, - MaxRejectReasonLen, MaxReserves, MaxSubsidyPeriod, MaxSwapFee, MaxTotalWeight, MaxWeight, - MinAssets, MinCategories, MinDisputeDuration, MinLiquidity, MinOracleDuration, MinSubsidy, - MinSubsidyPeriod, MinWeight, MinimumPeriod, PmPalletId, SimpleDisputesPalletId, - StakeWeight, SwapsPalletId, TreasuryPalletId, BASE, CENT, MILLISECS_PER_BLOCK, + AuthorizedPalletId, BalanceFractionalDecimals, BlockHashCount, CorrectionPeriod, + CourtCaseDuration, CourtPalletId, DisputeFactor, ExistentialDeposit, ExistentialDeposits, + ExitFee, GetNativeCurrencyId, LiquidityMiningPalletId, MaxApprovals, MaxAssets, + MaxCategories, MaxDisputeDuration, MaxDisputes, MaxEditReasonLen, MaxGracePeriod, + MaxInRatio, MaxMarketPeriod, MaxOracleDuration, MaxOutRatio, MaxRejectReasonLen, + MaxReserves, MaxSubsidyPeriod, MaxSwapFee, MaxTotalWeight, MaxWeight, MinAssets, + MinCategories, MinDisputeDuration, MinLiquidity, MinOracleDuration, MinSubsidy, + MinSubsidyPeriod, MinWeight, MinimumPeriod, PmPalletId, ReportPeriod, + SimpleDisputesPalletId, StakeWeight, SwapsPalletId, TreasuryPalletId, BASE, CENT, + MILLISECS_PER_BLOCK, }, types::{ AccountIdTest, Amount, Asset, Balance, BasicCurrencyAdapter, BlockNumber, BlockTest, diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index cb9e160de..1be98446d 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -33,6 +33,7 @@ mod pallet { use core::marker::PhantomData; use frame_support::{ dispatch::DispatchResult, + ensure, traits::{Currency, Get, Hooks, IsType}, PalletId, }; @@ -137,9 +138,10 @@ mod pallet { market_id: &Self::MarketId, market: &Market>, ) -> DispatchResult { - if market.dispute_mechanism != MarketDisputeMechanism::SimpleDisputes { - return Err(Error::::MarketDoesNotHaveSimpleDisputesMechanism.into()); - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::SimpleDisputes, + Error::::MarketDoesNotHaveSimpleDisputesMechanism + ); Self::remove_auto_resolve(disputes, market_id, market); let curr_block_num = >::block_number(); // each dispute resets dispute_duration @@ -154,12 +156,11 @@ mod pallet { _: &Self::MarketId, market: &Market>, ) -> Result, DispatchError> { - if market.dispute_mechanism != MarketDisputeMechanism::SimpleDisputes { - return Err(Error::::MarketDoesNotHaveSimpleDisputesMechanism.into()); - } - if market.status != MarketStatus::Disputed { - return Err(Error::::InvalidMarketStatus.into()); - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::SimpleDisputes, + Error::::MarketDoesNotHaveSimpleDisputesMechanism + ); + ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); if let Some(last_dispute) = disputes.last() { Ok(Some(last_dispute.outcome.clone())) @@ -173,9 +174,10 @@ mod pallet { _: &Self::MarketId, market: &Market>, ) -> Result, DispatchError> { - if market.dispute_mechanism != MarketDisputeMechanism::SimpleDisputes { - return Err(Error::::MarketDoesNotHaveSimpleDisputesMechanism.into()); - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::SimpleDisputes, + Error::::MarketDoesNotHaveSimpleDisputesMechanism + ); Ok(Self::get_auto_resolve(disputes, market)) } @@ -184,9 +186,10 @@ mod pallet { _: &Self::MarketId, market: &Market>, ) -> Result { - if market.dispute_mechanism != MarketDisputeMechanism::SimpleDisputes { - return Err(Error::::MarketDoesNotHaveSimpleDisputesMechanism.into()); - } + ensure!( + market.dispute_mechanism == MarketDisputeMechanism::SimpleDisputes, + Error::::MarketDoesNotHaveSimpleDisputesMechanism + ); // TODO when does simple disputes fail? Ok(false) } From 55dc26c30a1bc16b8ba0377e29d63874e2dfdcff Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 5 Dec 2022 14:33:33 +0100 Subject: [PATCH 29/93] check benchmark --- zrml/prediction-markets/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index c199970b8..670ff1942 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -492,7 +492,6 @@ mod pallet { /// # Weight /// /// Complexity: `O(n)`, where `n` is the number of outstanding disputes. - // TODO update benchmarks #[pallet::weight( T::WeightInfo::resolve_failed_mdm_authorized_categorical(T::MaxDisputes::get()) .max(T::WeightInfo::resolve_failed_mdm_authorized_scalar(T::MaxDisputes::get())) From e54dc31f5146d8adea7e0091296ef25a78682222 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 5 Dec 2022 14:39:34 +0100 Subject: [PATCH 30/93] remove where clauses --- zrml/prediction-markets/src/migrations.rs | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 226ff323c..a36864cd6 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -25,7 +25,6 @@ use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, BoundedVec, }; -use parity_scale_codec::EncodeLike; use sp_runtime::traits::{One, Saturating}; use zeitgeist_primitives::types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}; use zrml_authorized::Pallet as AuthorizedPallet; @@ -50,12 +49,6 @@ pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); // Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` impl OnRuntimeUpgrade for UpdateMarketIdsPerDisputeBlock -where - ::MarketId: - EncodeLike<<::MarketCommons as MarketCommonsPalletApi>::MarketId>, - ::MarketId: EncodeLike< - <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId, - >, { fn on_runtime_upgrade() -> Weight where @@ -337,10 +330,6 @@ pub struct AddFieldToAuthorityReport(PhantomData); // Add resolve_at block number value field to `AuthorizedOutcomeReports` map. impl OnRuntimeUpgrade for AddFieldToAuthorityReport -where - ::MarketId: EncodeLike< - <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId, - >, { fn on_runtime_upgrade() -> Weight where @@ -366,8 +355,8 @@ where total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); if let Some(outcome) = old_value { - let resolve_at: T::BlockNumber = now - .saturating_add(::ReportPeriod::get()); + let resolve_at: T::BlockNumber = + now.saturating_add(::ReportPeriod::get()); let new_value = AuthorityReport { resolve_at, outcome }; new_storage_map.push((key, new_value)); } From 3466a7391735c6ba8f19aaf4b1c62bcaa5d494e8 Mon Sep 17 00:00:00 2001 From: Chralt Date: Mon, 5 Dec 2022 14:41:38 +0100 Subject: [PATCH 31/93] Apply suggestions from code review Co-authored-by: Malte Kliemann --- primitives/src/traits/dispute_api.rs | 4 ++-- zrml/authorized/src/lib.rs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 3647ff21f..3d7b5996e 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -69,7 +69,7 @@ pub trait DisputeApi { /// /// # Returns /// - /// Returns true, when the dispute mechanism failed. Otherwise false. + /// Returns `true` if the dispute mechanism failed. Otherwise `false`. fn is_fail( disputes: &[MarketDispute], market_id: &Self::MarketId, @@ -86,7 +86,7 @@ pub trait DisputeResolutionApi { /// 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`).** + /// **mechanism is ready for the resolution ([`DisputeApi::on_resolution`]).** /// /// # Returns /// diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index ee38c132b..46e1c996e 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -121,7 +121,6 @@ mod pallet { Moment = MomentOf, >; - /// Market commons type MarketCommonsAuthorized: MarketCommonsPalletApi< AccountId = Self::AccountId, BlockNumber = Self::BlockNumber, From 45e51baff17e7cada11c6dbae13d5066950cae7c Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 6 Dec 2022 09:39:38 +0100 Subject: [PATCH 32/93] add empty commit From 965478095708d07d99e9b67ff54091291abcc953 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 6 Dec 2022 10:06:20 +0100 Subject: [PATCH 33/93] use Weight instead of u64 --- primitives/src/traits/dispute_api.rs | 4 ++-- zrml/authorized/src/mock.rs | 4 ++-- zrml/court/src/mock.rs | 4 ++-- zrml/prediction-markets/src/lib.rs | 2 +- zrml/simple-disputes/src/mock.rs | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 3d7b5996e..307b351a9 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -16,7 +16,7 @@ // along with Zeitgeist. If not, see . use crate::{market::MarketDispute, outcome_report::OutcomeReport, types::Market}; -use frame_support::dispatch::DispatchResult; +use frame_support::{dispatch::DispatchResult, pallet_prelude::Weight}; use sp_runtime::DispatchError; pub trait DisputeApi { @@ -94,7 +94,7 @@ pub trait DisputeResolutionApi { fn resolve( market_id: &Self::MarketId, market: &Market, - ) -> Result; + ) -> Result; /// Add a future block resolution of a disputed market. /// diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index c3d2f08ae..3237fff28 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -19,7 +19,7 @@ use crate::{self as zrml_authorized}; use frame_support::{ - construct_runtime, ord_parameter_types, pallet_prelude::DispatchError, traits::Everything, + construct_runtime, ord_parameter_types, pallet_prelude::{DispatchError, Weight}, traits::Everything, }; use frame_system::EnsureSignedBy; use sp_runtime::{ @@ -73,7 +73,7 @@ impl DisputeResolutionApi for NoopResolution { fn resolve( _market_id: &Self::MarketId, _market: &Market, - ) -> Result { + ) -> Result { Ok(0) } diff --git a/zrml/court/src/mock.rs b/zrml/court/src/mock.rs index 717f6ceb8..a66b25cbc 100644 --- a/zrml/court/src/mock.rs +++ b/zrml/court/src/mock.rs @@ -19,7 +19,7 @@ use crate::{self as zrml_court}; use frame_support::{ - construct_runtime, pallet_prelude::DispatchError, parameter_types, traits::Everything, PalletId, + construct_runtime, pallet_prelude::{DispatchError, Weight}, parameter_types, traits::Everything, PalletId, }; use sp_runtime::{ testing::Header, @@ -74,7 +74,7 @@ impl DisputeResolutionApi for NoopResolution { fn resolve( _market_id: &Self::MarketId, _market: &Market, - ) -> Result { + ) -> Result { Ok(0) } diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 670ff1942..36621508f 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -2455,7 +2455,7 @@ mod pallet { pub fn on_resolution( market_id: &MarketIdOf, market: &MarketOf, - ) -> Result { + ) -> Result { if market.creation == MarketCreation::Permissionless { T::AssetManager::unreserve_named( &Self::reserve_id(), diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index dfb45e580..0951736f9 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -18,7 +18,7 @@ #![cfg(test)] use crate::{self as zrml_simple_disputes}; -use frame_support::{construct_runtime, pallet_prelude::DispatchError, traits::Everything}; +use frame_support::{construct_runtime, pallet_prelude::{DispatchError, Weight}, traits::Everything}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, @@ -61,7 +61,7 @@ impl DisputeResolutionApi for NoopResolution { fn resolve( _market_id: &Self::MarketId, _market: &Market, - ) -> Result { + ) -> Result { Ok(0) } From 27721f66a95ceda231a80804b69e655e99976161 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 6 Dec 2022 10:07:50 +0100 Subject: [PATCH 34/93] resolve doc comment --- primitives/src/traits/dispute_api.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 307b351a9..43bd942ab 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -83,10 +83,10 @@ pub trait DisputeResolutionApi { type MarketId; type Moment; - /// Resolve a market. Fails if `on_resolution` from zrml-prediction-markets fails. + /// Resolve a market. /// - /// **Should only be called if the market dispute** - /// **mechanism is ready for the resolution ([`DisputeApi::on_resolution`]).** + /// **Should** only be called if the market dispute + /// mechanism is ready for the resolution ([`DisputeApi::on_resolution`]). /// /// # Returns /// From 56d0319264714b07a1f11efdfc77f0961c8b2839 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 6 Dec 2022 10:19:51 +0100 Subject: [PATCH 35/93] rename MarketCommonsAuthorized to MarketCommons --- runtime/common/src/lib.rs | 2 +- zrml/authorized/src/benchmarks.rs | 6 +- zrml/authorized/src/lib.rs | 10 +-- zrml/authorized/src/mock.rs | 2 +- zrml/prediction-markets/src/benchmarks.rs | 88 ++++++++++++----------- zrml/prediction-markets/src/mock.rs | 2 +- 6 files changed, 56 insertions(+), 54 deletions(-) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index b49a56d59..1fa2412f8 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -922,7 +922,7 @@ macro_rules! impl_config_traits { type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = zrml_prediction_markets::Pallet; type Event = Event; - type MarketCommonsAuthorized = MarketCommons; + type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; type ReportPeriod = ReportPeriod; type WeightInfo = zrml_authorized::weights::WeightInfo; diff --git a/zrml/authorized/src/benchmarks.rs b/zrml/authorized/src/benchmarks.rs index 844fdb1c5..08db63f3a 100644 --- a/zrml/authorized/src/benchmarks.rs +++ b/zrml/authorized/src/benchmarks.rs @@ -44,7 +44,7 @@ benchmarks! { let origin = T::AuthorizedDisputeResolutionOrigin::successful_origin(); let market_id = 0u32.into(); let market = market_mock::(); - T::MarketCommonsAuthorized::push_market(market).unwrap(); + T::MarketCommons::push_market(market).unwrap(); let call = Call::::authorize_market_outcome { market_id, outcome: OutcomeReport::Scalar(1), @@ -55,14 +55,14 @@ benchmarks! { let resolve_at = now.saturating_add(T::CorrectionPeriod::get() - 1u32.into()); let report = AuthorityReport { resolve_at, outcome: OutcomeReport::Scalar(0) }; for _ in 1..=m { - let id = T::MarketCommonsAuthorized::push_market(market_mock::()).unwrap(); + let id = T::MarketCommons::push_market(market_mock::()).unwrap(); T::DisputeResolution::add_auto_resolve(&id, resolve_at).unwrap(); } AuthorizedOutcomeReports::::insert(market_id, report); let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); for _ in 1..=d { - let id = T::MarketCommonsAuthorized::push_market(market_mock::()).unwrap(); + let id = T::MarketCommons::push_market(market_mock::()).unwrap(); T::DisputeResolution::add_auto_resolve(&id, correction_period_ends_at).unwrap(); } }: { call.dispatch_bypass_filter(origin)? } diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 46e1c996e..071c4ae90 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -58,11 +58,11 @@ mod pallet { pub(crate) type BalanceOf = as Currency<::AccountId>>::Balance; pub(crate) type CurrencyOf = - <::MarketCommonsAuthorized as MarketCommonsPalletApi>::Currency; + <::MarketCommons as MarketCommonsPalletApi>::Currency; pub(crate) type MarketIdOf = - <::MarketCommonsAuthorized as MarketCommonsPalletApi>::MarketId; + <::MarketCommons as MarketCommonsPalletApi>::MarketId; pub(crate) type MomentOf = - <::MarketCommonsAuthorized as MarketCommonsPalletApi>::Moment; + <::MarketCommons as MarketCommonsPalletApi>::Moment; pub type CacheSize = ConstU32<64>; @@ -80,7 +80,7 @@ mod pallet { outcome: OutcomeReport, ) -> DispatchResultWithPostInfo { T::AuthorizedDisputeResolutionOrigin::ensure_origin(origin)?; - let market = T::MarketCommonsAuthorized::market(&market_id)?; + let market = T::MarketCommons::market(&market_id)?; ensure!(market.status == MarketStatus::Disputed, Error::::MarketIsNotDisputed); ensure!(market.matches_outcome_report(&outcome), Error::::OutcomeMismatch); ensure!( @@ -121,7 +121,7 @@ mod pallet { Moment = MomentOf, >; - type MarketCommonsAuthorized: MarketCommonsPalletApi< + type MarketCommons: MarketCommonsPalletApi< AccountId = Self::AccountId, BlockNumber = Self::BlockNumber, >; diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 3237fff28..f19bf293a 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -94,7 +94,7 @@ impl crate::Config for Runtime { type Event = (); type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = NoopResolution; - type MarketCommonsAuthorized = MarketCommons; + type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; type AuthorizedDisputeResolutionOrigin = EnsureSignedBy; diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 2d5e70d7b..f8d856e95 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -98,7 +98,7 @@ fn create_market_common( scoring_rule, } .dispatch_bypass_filter(RawOrigin::Signed(caller.clone()).into())?; - let market_id = T::MarketCommons::latest_market_id()?; + let market_id = ::MarketCommons::latest_market_id()?; Ok((caller, market_id)) } @@ -114,7 +114,7 @@ fn create_close_and_report_market( create_market_common::(permission, options, ScoringRule::CPMM, Some(period))?; Call::::admin_move_market_to_closed { market_id } .dispatch_bypass_filter(T::CloseOrigin::successful_origin())?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let end: u32 = match market.period { MarketPeriod::Timestamp(range) => range.end.saturated_into::(), _ => { @@ -157,7 +157,7 @@ fn setup_redeem_shares_common( let close_origin = T::CloseOrigin::successful_origin(); let resolve_origin = T::ResolveOrigin::successful_origin(); Call::::admin_move_market_to_closed { market_id }.dispatch_bypass_filter(close_origin)?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let end: u32 = match market.period { MarketPeriod::Timestamp(range) => range.end.saturated_into::(), _ => { @@ -201,7 +201,7 @@ fn setup_reported_categorical_market_with_pool::admin_move_market_to_closed { market_id } .dispatch_bypass_filter(T::CloseOrigin::successful_origin())?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let end: u32 = match market.period { MarketPeriod::Timestamp(range) => range.end.saturated_into::(), _ => { @@ -239,7 +239,7 @@ benchmarks! { OutcomeReport::Categorical(0u16), )?; - let pool_id = T::MarketCommons::market_pool(&market_id)?; + let pool_id = ::MarketCommons::market_pool(&market_id)?; for i in 1..=d { let outcome = OutcomeReport::Categorical((i % a).saturated_into()); @@ -249,7 +249,7 @@ benchmarks! { let _ = Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; } - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let (range_start, range_end) = match market.period { MarketPeriod::Timestamp(range) => (range.start, range.end), @@ -303,9 +303,9 @@ benchmarks! { OutcomeReport::Categorical(0u16), )?; - let pool_id = T::MarketCommons::market_pool(&market_id)?; + let pool_id = ::MarketCommons::market_pool(&market_id)?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let (range_start, range_end) = match market.period { MarketPeriod::Timestamp(range) => (range.start, range.end), @@ -385,7 +385,7 @@ benchmarks! { OutcomeReport::Scalar(u128::MAX), )?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let report_at = market.report.unwrap().at; let resolves_at = report_at.saturating_add(market.deadlines.dispute_duration); @@ -416,12 +416,12 @@ benchmarks! { categories.into(), OutcomeReport::Categorical(0u16), )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let report_at = market.report.unwrap().at; let resolves_at = report_at.saturating_add(market.deadlines.dispute_duration); @@ -454,12 +454,12 @@ benchmarks! { OutcomeReport::Scalar(u128::MAX), )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; if let MarketType::Scalar(range) = market.market_type { assert!((d as u128) < *range.end()); } else { @@ -511,7 +511,7 @@ benchmarks! { OutcomeReport::Categorical(0u16) )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; @@ -529,7 +529,7 @@ benchmarks! { } let disputes = Disputes::::get(market_id); let last_dispute = disputes.last().unwrap(); - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let resolves_at = last_dispute.at.saturating_add(market.deadlines.dispute_duration); for i in 0..r { MarketIdsPerDisputeBlock::::try_mutate( @@ -638,7 +638,7 @@ benchmarks! { scoring_rule, } .dispatch_bypass_filter(RawOrigin::Signed(caller.clone()).into())?; - let market_id = T::MarketCommons::latest_market_id()?; + let market_id = ::MarketCommons::latest_market_id()?; let approve_origin = T::ApproveOrigin::successful_origin(); let edit_reason = vec![0_u8; 1024]; @@ -682,7 +682,7 @@ benchmarks! { )?; assert!( - Pallet::::calculate_time_frame_of_moment(T::MarketCommons::now()) + Pallet::::calculate_time_frame_of_moment(::MarketCommons::now()) < Pallet::::calculate_time_frame_of_moment(range_start) ); @@ -728,7 +728,7 @@ benchmarks! { // We need to ensure, that period range start is now, // because we would like to open the pool now - let range_start: MomentOf = T::MarketCommons::now(); + let range_start: MomentOf = ::MarketCommons::now(); let range_end: MomentOf = 1_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, @@ -737,7 +737,7 @@ benchmarks! { Some(MarketPeriod::Timestamp(range_start..range_end)), )?; - let market = T::MarketCommons::market(&market_id.saturated_into())?; + let market = ::MarketCommons::market(&market_id.saturated_into())?; let max_swap_fee: BalanceOf:: = MaxSwapFee::get().saturated_into(); let min_liquidity: BalanceOf:: = MinLiquidity::get().saturated_into(); @@ -759,7 +759,9 @@ benchmarks! { }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } verify { - let market_pool_id = T::MarketCommons::market_pool(&market_id.saturated_into())?; + let market_pool_id = ::MarketCommons::market_pool( + &market_id.saturated_into(), + )?; let pool = T::Swaps::pool(market_pool_id)?; assert_eq!(pool.pool_status, PoolStatus::Active); } @@ -820,12 +822,12 @@ benchmarks! { report_outcome, )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; if let MarketType::Scalar(range) = market.market_type { assert!((d as u128) < *range.end()); } else { @@ -854,12 +856,12 @@ benchmarks! { report_outcome, )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; if let MarketType::Scalar(range) = market.market_type { assert!((d as u128) < *range.end()); } else { @@ -896,7 +898,7 @@ benchmarks! { OutcomeReport::Categorical(0u16) )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; @@ -934,7 +936,7 @@ benchmarks! { ScoringRule::CPMM, Some(MarketPeriod::Timestamp(T::MinSubsidyPeriod::get()..T::MaxSubsidyPeriod::get())), )?; - let market = T::MarketCommons::market(&market_id.saturated_into())?; + let market = ::MarketCommons::market(&market_id.saturated_into())?; }: { Pallet::::handle_expired_advised_market(&market_id, market)? } internal_resolve_categorical_reported { @@ -943,15 +945,15 @@ benchmarks! { categories.into(), OutcomeReport::Categorical(1u16), )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; }: { Pallet::::on_resolution(&market_id, &market)?; } verify { - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; assert_eq!(market.status, MarketStatus::Resolved); } @@ -965,7 +967,7 @@ benchmarks! { categories.into(), OutcomeReport::Categorical(1u16) )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; @@ -978,11 +980,11 @@ benchmarks! { OutcomeReport::Categorical((i % 2).saturated_into::()), )?; } - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; }: { Pallet::::on_resolution(&market_id, &market)?; } verify { - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; assert_eq!(market.status, MarketStatus::Resolved); } @@ -992,11 +994,11 @@ benchmarks! { MarketType::Scalar(0u128..=u128::MAX), OutcomeReport::Scalar(u128::MAX), )?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; }: { Pallet::::on_resolution(&market_id, &market)?; } verify { - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; assert_eq!(market.status, MarketStatus::Resolved); } @@ -1008,11 +1010,11 @@ benchmarks! { MarketType::Scalar(0u128..=u128::MAX), OutcomeReport::Scalar(u128::MAX), )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; if let MarketType::Scalar(range) = market.market_type { assert!((d as u128) < *range.end()); } else { @@ -1026,11 +1028,11 @@ benchmarks! { OutcomeReport::Scalar(i.into()) )?; } - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; }: { Pallet::::on_resolution(&market_id, &market)?; } verify { - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; assert_eq!(market.status, MarketStatus::Resolved); } @@ -1107,7 +1109,7 @@ benchmarks! { let m in 0..63; // ensure range.start is now to get the heaviest path - let range_start: MomentOf = T::MarketCommons::now(); + let range_start: MomentOf = ::MarketCommons::now(); let range_end: MomentOf = 1_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, @@ -1116,7 +1118,7 @@ benchmarks! { Some(MarketPeriod::Timestamp(range_start..range_end)), )?; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { // ensure sender is oracle to succeed extrinsic call market.oracle = caller.clone(); Ok(()) @@ -1125,7 +1127,7 @@ benchmarks! { let outcome = OutcomeReport::Categorical(0); let close_origin = T::CloseOrigin::successful_origin(); Pallet::::admin_move_market_to_closed(close_origin, market_id)?; - let market = T::MarketCommons::market(&market_id)?; + let market = ::MarketCommons::market(&market_id)?; let end : u32 = match market.period { MarketPeriod::Timestamp(range) => { range.end.saturated_into::() @@ -1176,7 +1178,7 @@ benchmarks! { Some(MarketPeriod::Timestamp(T::MinSubsidyPeriod::get()..T::MaxSubsidyPeriod::get())), )?; let mut market_clone = None; - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.status = MarketStatus::CollectingSubsidy; market_clone = Some(market.clone()); Ok(()) @@ -1261,7 +1263,7 @@ benchmarks! { Some(MarketPeriod::Timestamp(range_start..range_end)), )?; // ensure market is reported - T::MarketCommons::mutate_market(&market_id, |market| { + ::MarketCommons::mutate_market(&market_id, |market| { market.status = MarketStatus::Reported; Ok(()) })?; diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 262efb6e3..1f2bd86ff 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -264,7 +264,7 @@ impl zrml_authorized::Config for Runtime { type CorrectionPeriod = CorrectionPeriod; type Event = Event; type DisputeResolution = prediction_markets::Pallet; - type MarketCommonsAuthorized = MarketCommons; + type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; type WeightInfo = zrml_authorized::weights::WeightInfo; } From 6628a46f4f7d53afb3c0295e893bedf24c1c009d Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 6 Dec 2022 10:21:57 +0100 Subject: [PATCH 36/93] fmt --- zrml/authorized/src/lib.rs | 3 +-- zrml/authorized/src/mock.rs | 4 +++- zrml/court/src/mock.rs | 6 +++++- zrml/simple-disputes/src/mock.rs | 6 +++++- 4 files changed, 14 insertions(+), 5 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 071c4ae90..889b729f8 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -61,8 +61,7 @@ mod pallet { <::MarketCommons as MarketCommonsPalletApi>::Currency; pub(crate) type MarketIdOf = <::MarketCommons as MarketCommonsPalletApi>::MarketId; - pub(crate) type MomentOf = - <::MarketCommons as MarketCommonsPalletApi>::Moment; + pub(crate) type MomentOf = <::MarketCommons as MarketCommonsPalletApi>::Moment; pub type CacheSize = ConstU32<64>; diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index f19bf293a..7113274a3 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -19,7 +19,9 @@ use crate::{self as zrml_authorized}; use frame_support::{ - construct_runtime, ord_parameter_types, pallet_prelude::{DispatchError, Weight}, traits::Everything, + construct_runtime, ord_parameter_types, + pallet_prelude::{DispatchError, Weight}, + traits::Everything, }; use frame_system::EnsureSignedBy; use sp_runtime::{ diff --git a/zrml/court/src/mock.rs b/zrml/court/src/mock.rs index a66b25cbc..567a40af1 100644 --- a/zrml/court/src/mock.rs +++ b/zrml/court/src/mock.rs @@ -19,7 +19,11 @@ use crate::{self as zrml_court}; use frame_support::{ - construct_runtime, pallet_prelude::{DispatchError, Weight}, parameter_types, traits::Everything, PalletId, + construct_runtime, + pallet_prelude::{DispatchError, Weight}, + parameter_types, + traits::Everything, + PalletId, }; use sp_runtime::{ testing::Header, diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index 0951736f9..163ab57d1 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -18,7 +18,11 @@ #![cfg(test)] use crate::{self as zrml_simple_disputes}; -use frame_support::{construct_runtime, pallet_prelude::{DispatchError, Weight}, traits::Everything}; +use frame_support::{ + construct_runtime, + pallet_prelude::{DispatchError, Weight}, + traits::Everything, +}; use sp_runtime::{ testing::Header, traits::{BlakeTwo256, IdentityLookup}, From a72518131f53e3abe5c7d7552f899d467956b2a5 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 7 Dec 2022 15:18:18 +0100 Subject: [PATCH 37/93] allow only one dispute for authorized --- zrml/authorized/src/lib.rs | 12 ++- zrml/prediction-markets/src/tests.rs | 122 ++++++++------------------- 2 files changed, 40 insertions(+), 94 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 889b729f8..af4d05462 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -138,14 +138,14 @@ mod pallet { #[pallet::error] pub enum Error { - /// The authority already made its report. - AuthorityAlreadyReported, /// An unauthorized account attempts to submit a report. NotAuthorizedForThisMarket, /// The market unexpectedly has the incorrect dispute mechanism. MarketDoesNotHaveDisputeMechanismAuthorized, /// An account attempts to submit a report to an undisputed market. MarketIsNotDisputed, + /// Only one dispute is allowed. + OnlyOneDisputeAllowed, /// The report does not match the market's type. OutcomeMismatch, /// The market should be reported at this point. @@ -193,17 +193,15 @@ mod pallet { type Origin = T::Origin; fn on_dispute( - _: &[MarketDispute], - market_id: &Self::MarketId, + disputes: &[MarketDispute], + _: &Self::MarketId, market: &Market, ) -> DispatchResult { ensure!( market.dispute_mechanism == MarketDisputeMechanism::Authorized, Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - if AuthorizedOutcomeReports::::get(market_id).is_some() { - return Err(Error::::AuthorityAlreadyReported.into()); - } + ensure!(disputes.len() == 0usize, Error::::OnlyOneDisputeAllowed); Ok(()) } diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 16adc593c..688ba8cf3 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2059,7 +2059,7 @@ fn dispute_fails_authority_reported_already() { assert_noop!( PredictionMarkets::dispute(Origin::signed(CHARLIE), 0, OutcomeReport::Categorical(1)), - AuthorizedError::::AuthorityAlreadyReported + AuthorizedError::::OnlyOneDisputeAllowed ); }); } @@ -2313,32 +2313,17 @@ fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { 0, OutcomeReport::Categorical(0) )); - let dispute_at_0 = end + grace_period + 2; - run_to_block(dispute_at_0); + let dispute_at = end + grace_period + 2; + run_to_block(dispute_at); assert_ok!(PredictionMarkets::dispute( Origin::signed(CHARLIE), 0, OutcomeReport::Categorical(1) )); - let dispute_at_1 = dispute_at_0 + 1; - run_to_block(dispute_at_1); - assert_ok!(PredictionMarkets::dispute( - Origin::signed(DAVE), - 0, - OutcomeReport::Categorical(0) - )); - let dispute_at_2 = dispute_at_1 + 1; - run_to_block(dispute_at_2); - assert_ok!(PredictionMarkets::dispute( - Origin::signed(EVE), - 0, - OutcomeReport::Categorical(1) - )); let charlie_reserved = Balances::reserved_balance(&CHARLIE); - let eve_reserved = Balances::reserved_balance(&EVE); let disputes = crate::Disputes::::get(0); - assert_eq!(disputes.len(), 3); + assert_eq!(disputes.len(), 1); run_blocks(::ReportPeriod::get() + 1); assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), 0)); @@ -2354,13 +2339,9 @@ fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { // slashed amounts // --------------------------- // - Charlie's reserve: DisputeBond::get() - // - Eve's reserve: DisputeBond::get() + 2 * DisputeFactor::get() - // - // All goes to Dave (because Bob is - strictly speaking - not a disputor). + // The market defaults on the report provided by the oracle. + // Charlie disputed a different outcome than the oracle reported. assert_eq!(Balances::free_balance(&CHARLIE), 1_000 * BASE - charlie_reserved); - assert_eq!(Balances::free_balance(&EVE), 1_000 * BASE - eve_reserved); - let total_slashed = charlie_reserved + eve_reserved; - assert_eq!(Balances::free_balance(&DAVE), 1_000 * BASE + total_slashed); // The oracle report was accepted, so Alice is not slashed. assert_eq!(Balances::free_balance(&ALICE), 1_000 * BASE); @@ -2497,16 +2478,15 @@ fn start_global_dispute_fails_on_wrong_mdm() { let dispute_at_0 = end + grace_period + 2; run_to_block(dispute_at_0); - for i in 1..=::MaxDisputes::get() { - assert_ok!(PredictionMarkets::dispute( - Origin::signed(CHARLIE), - market_id, - OutcomeReport::Categorical(i.saturated_into()) - )); - run_blocks(1); - let market = MarketCommons::market(&market_id).unwrap(); - assert_eq!(market.status, MarketStatus::Disputed); - } + // only one dispute allowed for authorized mdm + assert_ok!(PredictionMarkets::dispute( + Origin::signed(CHARLIE), + market_id, + OutcomeReport::Categorical(1u32.saturated_into()) + )); + run_blocks(1); + let market = MarketCommons::market(&market_id).unwrap(); + assert_eq!(market.status, MarketStatus::Disputed); #[cfg(feature = "with-global-disputes")] assert_noop!( @@ -3078,28 +3058,20 @@ fn authorized_correctly_resolves_disputed_market() { 0, OutcomeReport::Categorical(0) )); - let dispute_at_0 = grace_period + 1 + 1; - run_to_block(dispute_at_0); + + let charlie_balance = Balances::free_balance(&CHARLIE); + assert_eq!(charlie_balance, 1_000 * BASE - CENT); + + let dispute_at = grace_period + 1 + 1; + run_to_block(dispute_at); assert_ok!(PredictionMarkets::dispute( Origin::signed(CHARLIE), 0, OutcomeReport::Categorical(1) )); - let dispute_at_1 = dispute_at_0 + 1; - run_to_block(dispute_at_1); - assert_ok!(PredictionMarkets::dispute( - Origin::signed(DAVE), - 0, - OutcomeReport::Categorical(0) - )); - let dispute_at_2 = dispute_at_1 + 1; - run_to_block(dispute_at_2); - assert_ok!(PredictionMarkets::dispute( - Origin::signed(EVE), - 0, - OutcomeReport::Categorical(1) - )); + let charlie_balance = Balances::free_balance(&CHARLIE); + assert_eq!(charlie_balance, 1_000 * BASE - CENT - DisputeBond::get()); // Fred authorizses an outcome, but fat-fingers it on the first try. assert_ok!(Authorized::authorize_market_outcome( @@ -3120,39 +3092,31 @@ fn authorized_correctly_resolves_disputed_market() { let charlie_reserved = Balances::reserved_balance(&CHARLIE); assert_eq!(charlie_reserved, DisputeBond::get()); - let dave_reserved = Balances::reserved_balance(&DAVE); - assert_eq!(dave_reserved, DisputeBond::get() + DisputeFactor::get()); - - let eve_reserved = Balances::reserved_balance(&EVE); - assert_eq!(eve_reserved, DisputeBond::get() + 2 * DisputeFactor::get()); - // check disputes length let disputes = crate::Disputes::::get(0); - assert_eq!(disputes.len(), 3); + assert_eq!(disputes.len(), 1); - // make sure the old mappings of market id per dispute block are erased let market_ids_1 = MarketIdsPerDisputeBlock::::get( - dispute_at_0 + ::CorrectionPeriod::get(), + dispute_at + ::CorrectionPeriod::get(), ); - assert_eq!(market_ids_1.len(), 0); + assert_eq!(market_ids_1.len(), 1); - let market_ids_2 = MarketIdsPerDisputeBlock::::get( - dispute_at_1 + ::CorrectionPeriod::get(), - ); - assert_eq!(market_ids_2.len(), 0); - - let market_ids_3 = MarketIdsPerDisputeBlock::::get( - dispute_at_2 + ::CorrectionPeriod::get(), - ); - assert_eq!(market_ids_3.len(), 1); + let charlie_balance = Balances::free_balance(&CHARLIE); + assert_eq!(charlie_balance, 1_000 * BASE - CENT - DisputeBond::get()); run_blocks(::CorrectionPeriod::get() - 1); let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Disputed); + let charlie_balance = Balances::free_balance(&CHARLIE); + assert_eq!(charlie_balance, 1_000 * BASE - CENT - DisputeBond::get()); + run_blocks(1); + let charlie_balance = Balances::free_balance(&CHARLIE); + assert_eq!(charlie_balance, 1_000 * BASE - CENT + OracleBond::get()); + let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); let disputes = crate::Disputes::::get(0); @@ -3160,26 +3124,10 @@ fn authorized_correctly_resolves_disputed_market() { assert_ok!(PredictionMarkets::redeem_shares(Origin::signed(CHARLIE), 0)); - // Make sure rewards are right: - // - // Slashed amounts: - // - Dave's reserve: DisputeBond::get() + DisputeFactor::get() - // - Alice's oracle bond: OracleBond::get() - // Total: OracleBond::get() + DisputeBond::get() + DisputeFactor::get() - // - // Charlie and Eve each receive half of the total slashed amount as bounty. - let dave_reserved = DisputeBond::get() + DisputeFactor::get(); - let total_slashed = OracleBond::get() + dave_reserved; - let charlie_balance = Balances::free_balance(&CHARLIE); - assert_eq!(charlie_balance, 1_000 * BASE + total_slashed / 2); + assert_eq!(charlie_balance, 1_000 * BASE + OracleBond::get()); let charlie_reserved_2 = Balances::reserved_balance(&CHARLIE); assert_eq!(charlie_reserved_2, 0); - let eve_balance = Balances::free_balance(&EVE); - assert_eq!(eve_balance, 1_000 * BASE + total_slashed / 2); - - let dave_balance = Balances::free_balance(&DAVE); - assert_eq!(dave_balance, 1_000 * BASE - dave_reserved); let alice_balance = Balances::free_balance(&ALICE); assert_eq!(alice_balance, 1_000 * BASE - OracleBond::get()); From 09ab27b5500db506174ae21a221a4bfeefef5f69 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 8 Dec 2022 10:40:38 +0100 Subject: [PATCH 38/93] clippy --- zrml/authorized/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index af4d05462..63020550f 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -201,7 +201,7 @@ mod pallet { market.dispute_mechanism == MarketDisputeMechanism::Authorized, Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - ensure!(disputes.len() == 0usize, Error::::OnlyOneDisputeAllowed); + ensure!(disputes.is_empty(), Error::::OnlyOneDisputeAllowed); Ok(()) } From 02ecf9c114c7d6282f2f6a29698abd65370998a7 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 8 Dec 2022 12:54:29 +0100 Subject: [PATCH 39/93] fix benchmarks after one dispute limit authorized --- zrml/prediction-markets/src/benchmarks.rs | 91 ++++++++++------------- 1 file changed, 41 insertions(+), 50 deletions(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index f8d856e95..e97017c17 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -76,14 +76,15 @@ fn create_market_common_parameters( } // Create a market based on common parameters -fn create_market_common( +fn create_market_common( permission: MarketCreation, options: MarketType, scoring_rule: ScoringRule, period: Option>>, ) -> Result<(T::AccountId, MarketIdOf), &'static str> { + pallet_timestamp::Pallet::::set_timestamp(0u32.into()); let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); let period = period.unwrap_or(MarketPeriod::Timestamp(range_start..range_end)); let (caller, oracle, deadlines, metadata, creation) = create_market_common_parameters::(permission)?; @@ -108,7 +109,7 @@ fn create_close_and_report_market( outcome: OutcomeReport, ) -> Result<(T::AccountId, MarketIdOf), &'static str> { let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); let period = MarketPeriod::Timestamp(range_start..range_end); let (caller, market_id) = create_market_common::(permission, options, ScoringRule::CPMM, Some(period))?; @@ -350,7 +351,7 @@ benchmarks! { let c in 0..63; let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, MarketType::Categorical(T::MaxCategories::get()), @@ -455,7 +456,7 @@ benchmarks! { )?; ::MarketCommons::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; Ok(()) })?; @@ -493,10 +494,11 @@ benchmarks! { }: { call.dispatch_bypass_filter(close_origin)? } verify { + // simple disputes resolves to the last dispute outcome assert_last_event::(Event::MarketResolved::( market_id, MarketStatus::Resolved, - OutcomeReport::Scalar(u128::MAX), + OutcomeReport::Scalar(d.into()), ).into()); } @@ -512,7 +514,7 @@ benchmarks! { )?; ::MarketCommons::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; Ok(()) })?; @@ -546,7 +548,7 @@ benchmarks! { assert_last_event::(Event::MarketResolved::( market_id, MarketStatus::Resolved, - OutcomeReport::Categorical(0u16), + OutcomeReport::Categorical((d % 2).saturated_into::()), ).into()); } @@ -623,7 +625,7 @@ benchmarks! { let dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; let scoring_rule = ScoringRule::CPMM; let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); let period = MarketPeriod::Timestamp(range_start..range_end); let (caller, oracle, deadlines, metadata, creation) = create_market_common_parameters::(MarketCreation::Advised)?; @@ -673,7 +675,7 @@ benchmarks! { let o in 0..63; let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, MarketType::Categorical(a.saturated_into()), @@ -729,7 +731,7 @@ benchmarks! { // We need to ensure, that period range start is now, // because we would like to open the pool now let range_start: MomentOf = ::MarketCommons::now(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, MarketType::Categorical(a.saturated_into()), @@ -813,8 +815,6 @@ benchmarks! { } dispute_authorized { - let d in 0..(T::MaxDisputes::get() - 1); - let report_outcome = OutcomeReport::Scalar(u128::MAX); let (caller, market_id) = create_close_and_report_market::( MarketCreation::Permissionless, @@ -829,26 +829,19 @@ benchmarks! { let market = ::MarketCommons::market(&market_id)?; if let MarketType::Scalar(range) = market.market_type { - assert!((d as u128) < *range.end()); + assert!(1u128 < *range.end()); } else { panic!("Must create scalar market"); } - for i in 0..d { - let outcome = OutcomeReport::Scalar(i.into()); - let disputor = account("disputor", i, 0); - T::AssetManager::deposit(Asset::Ztg, &disputor, (u128::MAX).saturated_into())?; - Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; - } - let dispute_outcome = OutcomeReport::Scalar((d + 1).into()); + // only one dispute allowed for authorized mdm + let dispute_outcome = OutcomeReport::Scalar(1u128.into()); let call = Call::::dispute { market_id, outcome: dispute_outcome }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } resolve_failed_mdm_authorized_scalar { - let d in 1..T::MaxDisputes::get(); - let report_outcome = OutcomeReport::Scalar(u128::MAX); let (caller, market_id) = create_close_and_report_market::( MarketCreation::Permissionless, @@ -863,16 +856,16 @@ benchmarks! { let market = ::MarketCommons::market(&market_id)?; if let MarketType::Scalar(range) = market.market_type { - assert!((d as u128) < *range.end()); + assert!(1u128 < *range.end()); } else { panic!("Must create scalar market"); } - for i in 1..=d { - let outcome = OutcomeReport::Scalar(i.into()); - let disputor = account("disputor", i, 0); - T::AssetManager::deposit(Asset::Ztg, &disputor, (u128::MAX).saturated_into())?; - Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; - } + + // authorize mdm allows only one dispute + let outcome = OutcomeReport::Scalar(1u128); + let disputor = account("disputor", 0, 0); + T::AssetManager::deposit(Asset::Ztg, &disputor, (u128::MAX).saturated_into())?; + Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; let authority_report_period = ::ReportPeriod::get(); let now = >::block_number(); @@ -889,8 +882,6 @@ benchmarks! { } resolve_failed_mdm_authorized_categorical { - let d in 1..T::MaxDisputes::get(); - let categories = T::MaxCategories::get(); let (caller, market_id) = setup_reported_categorical_market_with_pool::( @@ -903,17 +894,16 @@ 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)?; - } + // authorize mdm allows only one dispute + let outcome = OutcomeReport::Categorical(1u16); + let disputor = account("disputor", 0, 0); + let dispute_bond = crate::pallet::default_dispute_bond::(0 as usize); + T::AssetManager::deposit( + Asset::Ztg, + &disputor, + dispute_bond, + )?; + Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; let authority_report_period = ::ReportPeriod::get(); let now = >::block_number(); @@ -968,7 +958,7 @@ benchmarks! { OutcomeReport::Categorical(1u16) )?; ::MarketCommons::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; Ok(()) })?; @@ -1011,7 +1001,8 @@ benchmarks! { OutcomeReport::Scalar(u128::MAX), )?; ::MarketCommons::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; + // to allow multiple disputes use simple disputes + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; Ok(()) })?; let market = ::MarketCommons::market(&market_id)?; @@ -1078,7 +1069,7 @@ benchmarks! { let r in 0..::MaxRejectReasonLen::get(); let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); let (_, market_id) = create_market_common::( MarketCreation::Advised, MarketType::Categorical(T::MaxCategories::get()), @@ -1110,7 +1101,7 @@ benchmarks! { // ensure range.start is now to get the heaviest path let range_start: MomentOf = ::MarketCommons::now(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, MarketType::Categorical(T::MaxCategories::get()), @@ -1191,7 +1182,7 @@ benchmarks! { // ensure markets exist let start_block: T::BlockNumber = 100_000u64.saturated_into(); - let end_block: T::BlockNumber = 1_000_000u64.saturated_into(); + let end_block: T::BlockNumber = 100_000_000u64.saturated_into(); for _ in 0..31 { create_market_common::( MarketCreation::Permissionless, @@ -1202,7 +1193,7 @@ benchmarks! { } let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); for _ in 31..64 { create_market_common::( MarketCreation::Permissionless, @@ -1253,7 +1244,7 @@ benchmarks! { let d in 1..31; let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 1_000_000u64.saturated_into(); + let range_end: MomentOf = 100_000_000u64.saturated_into(); // ensure markets exist for _ in 0..64 { let (_, market_id) = create_market_common::( From 7f6bc000176c10e6bd4fb15a17aa4a21445138c7 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 8 Dec 2022 12:58:38 +0100 Subject: [PATCH 40/93] fix clippy --- zrml/prediction-markets/src/benchmarks.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index e97017c17..fcbf7a433 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -835,7 +835,7 @@ benchmarks! { } // only one dispute allowed for authorized mdm - let dispute_outcome = OutcomeReport::Scalar(1u128.into()); + let dispute_outcome = OutcomeReport::Scalar(1u128); let call = Call::::dispute { market_id, outcome: dispute_outcome }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; @@ -897,7 +897,7 @@ benchmarks! { // authorize mdm allows only one dispute let outcome = OutcomeReport::Categorical(1u16); let disputor = account("disputor", 0, 0); - let dispute_bond = crate::pallet::default_dispute_bond::(0 as usize); + let dispute_bond = crate::pallet::default_dispute_bond::(0_usize); T::AssetManager::deposit( Asset::Ztg, &disputor, From 7c7098cf555572d1ab2e63d04cb3d18720ce7a64 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 8 Dec 2022 14:50:20 +0100 Subject: [PATCH 41/93] add try-runtime tests --- zrml/prediction-markets/src/migrations.rs | 38 ++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index a36864cd6..75a7dbb02 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -16,7 +16,7 @@ // along with Zeitgeist. If not, see . use crate::{CacheSize, Config, MarketIdOf, Pallet}; -use alloc::vec::Vec; +use alloc::{string::ToString, vec::Vec}; use frame_support::{ dispatch::Weight, log, @@ -25,6 +25,8 @@ use frame_support::{ traits::{Get, OnRuntimeUpgrade, StorageVersion}, BoundedVec, }; +#[cfg(feature = "try-runtime")] +use scale_info::prelude::format; use sp_runtime::traits::{One, Saturating}; use zeitgeist_primitives::types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}; use zrml_authorized::Pallet as AuthorizedPallet; @@ -380,11 +382,45 @@ impl OnRuntim #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { + use frame_support::traits::OnRuntimeUpgradeHelpersExt; + let counter_key = "counter_key".to_string(); + Self::set_temp_storage(0_u32, &counter_key); + for (key, value) in + storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) + { + Self::set_temp_storage(value, &format!("{:?}", key.as_slice())); + + let counter: u32 = + Self::get_temp_storage(&counter_key).expect("counter key storage not found"); + Self::set_temp_storage(counter + 1_u32, &counter_key); + } Ok(()) } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { + use frame_support::traits::OnRuntimeUpgradeHelpersExt; + let mut markets_count = 0_u32; + let old_counter_key = "counter_key".to_string(); + for (key, new_value) in storage_iter::>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + ) { + if let Some(AuthorityReport { resolve_at: _, outcome }) = new_value { + let old_value: Option = + Self::get_temp_storage(&format!("{:?}", key.as_slice())) + .expect("old value not found"); + + assert_eq!(old_value.unwrap(), outcome); + + markets_count += 1_u32; + } else { + panic!("storage iter should only find present (Option::Some) values"); + } + } + let old_markets_count: u32 = + Self::get_temp_storage(&old_counter_key).expect("old counter key storage not found"); + assert_eq!(markets_count, old_markets_count); Ok(()) } } From b6186055ba50873bd5a74b2b43c69b19b1405691 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 8 Dec 2022 15:06:11 +0100 Subject: [PATCH 42/93] correct benchmarks --- zrml/prediction-markets/src/lib.rs | 15 +- zrml/prediction-markets/src/weights.rs | 263 +++++++++++-------------- 2 files changed, 125 insertions(+), 153 deletions(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index a9cf8cf27..dcbe2341d 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -438,7 +438,7 @@ mod pallet { /// # Weight /// /// Complexity: `O(n)`, where `n` is the number of outstanding disputes. - #[pallet::weight(T::WeightInfo::dispute_authorized(T::MaxDisputes::get()))] + #[pallet::weight(T::WeightInfo::dispute_authorized())] #[transactional] pub fn dispute( origin: OriginFor, @@ -484,7 +484,7 @@ mod pallet { MarketStatus::Disputed, market_dispute, )); - Ok((Some(T::WeightInfo::dispute_authorized(num_disputes))).into()) + Ok((Some(T::WeightInfo::dispute_authorized())).into()) } /// Resolve the market, when the dispute mechanism failed. @@ -493,8 +493,8 @@ mod pallet { /// /// Complexity: `O(n)`, where `n` is the number of outstanding disputes. #[pallet::weight( - T::WeightInfo::resolve_failed_mdm_authorized_categorical(T::MaxDisputes::get()) - .max(T::WeightInfo::resolve_failed_mdm_authorized_scalar(T::MaxDisputes::get())) + T::WeightInfo::resolve_failed_mdm_authorized_categorical() + .max(T::WeightInfo::resolve_failed_mdm_authorized_scalar()) )] #[transactional] pub fn resolve_failed_mdm( @@ -505,7 +505,6 @@ mod pallet { let market = T::MarketCommons::market(&market_id)?; ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); let disputes = Disputes::::get(market_id); - let disputes_len = disputes.len() as u32; // TODO(#782): use multiple benchmarks paths for different dispute mechanisms let is_fail = match market.dispute_mechanism { MarketDisputeMechanism::Authorized => { @@ -523,11 +522,9 @@ mod pallet { Self::deposit_event(Event::DisputeMechanismFailed(market_id)); let weight = match market.market_type { - MarketType::Scalar(_) => { - T::WeightInfo::resolve_failed_mdm_authorized_scalar(disputes_len) - } + MarketType::Scalar(_) => T::WeightInfo::resolve_failed_mdm_authorized_scalar(), MarketType::Categorical(_) => { - T::WeightInfo::resolve_failed_mdm_authorized_categorical(disputes_len) + T::WeightInfo::resolve_failed_mdm_authorized_categorical() } }; diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index 4af1572de..16abf40e8 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -59,10 +59,10 @@ pub trait WeightInfoZeitgeist { fn edit_market(m: u32) -> Weight; fn deploy_swap_pool_for_market_future_pool(a: u32, o: u32) -> Weight; fn deploy_swap_pool_for_market_open_pool(a: u32) -> Weight; - fn dispute_authorized(d: u32) -> Weight; - fn resolve_failed_mdm_authorized_scalar(d: u32) -> Weight; - fn resolve_failed_mdm_authorized_categorical(d: u32) -> Weight; fn start_global_dispute(m: u32) -> Weight; + fn dispute_authorized() -> Weight; + fn resolve_failed_mdm_authorized_scalar() -> Weight; + fn resolve_failed_mdm_authorized_categorical() -> Weight; fn handle_expired_advised_market() -> Weight; fn internal_resolve_categorical_reported() -> Weight; fn internal_resolve_categorical_disputed(d: u32) -> Weight; @@ -93,12 +93,12 @@ 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 { - (176_251_000 as Weight) - // Standard Error: 14_000 - .saturating_add((37_179_000 as Weight).saturating_mul(a as Weight)) - // Standard Error: 218_000 - .saturating_add((6_261_000 as Weight).saturating_mul(d as Weight)) + fn admin_destroy_disputed_market(a: u32, _d: u32, _o: u32, _c: u32, r: u32) -> Weight { + (207_687_000 as Weight) + // Standard Error: 53_000 + .saturating_add((22_986_000 as Weight).saturating_mul(a as Weight)) + // Standard Error: 52_000 + .saturating_add((276_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(8 as Weight)) @@ -114,11 +114,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerReportBlock (r:1 w:1) // Storage: PredictionMarkets Disputes (r:0 w:1) fn admin_destroy_reported_market(a: u32, _o: u32, c: u32, _r: u32) -> Weight { - (198_500_000 as Weight) - // Standard Error: 16_000 - .saturating_add((37_042_000 as Weight).saturating_mul(a as Weight)) - // Standard Error: 15_000 - .saturating_add((218_000 as Weight).saturating_mul(c as Weight)) + (122_080_000 as Weight) + // Standard Error: 11_000 + .saturating_add((22_824_000 as Weight).saturating_mul(a as Weight)) + // Standard Error: 10_000 + .saturating_add((56_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(8 as Weight)) @@ -128,10 +128,12 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerOpenTimeFrame (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerCloseTimeFrame (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) - fn admin_move_market_to_closed(_o: u32, c: u32) -> Weight { - (62_877_000 as Weight) - // Standard Error: 0 - .saturating_add((71_000 as Weight).saturating_mul(c as Weight)) + fn admin_move_market_to_closed(o: u32, c: u32) -> Weight { + (37_778_000 as Weight) + // Standard Error: 1_000 + .saturating_add((10_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 1_000 + .saturating_add((18_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -141,9 +143,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) fn admin_move_market_to_resolved_scalar_reported(r: u32) -> Weight { - (100_354_000 as Weight) - // Standard Error: 0 - .saturating_add((80_000 as Weight).saturating_mul(r as Weight)) + (65_196_000 as Weight) + // Standard Error: 2_000 + .saturating_add((35_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -154,9 +156,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: Swaps Pools (r:1 w:1) fn admin_move_market_to_resolved_categorical_reported(r: u32) -> Weight { - (201_548_000 as Weight) - // Standard Error: 3_000 - .saturating_add((100_000 as Weight).saturating_mul(r as Weight)) + (93_157_000 as Weight) + // Standard Error: 6_000 + .saturating_add((61_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -164,55 +166,51 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) // Storage: Balances Reserves (r:7 w:7) - // Storage: GlobalDisputes Winners (r:1 w:0) - // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) - // Storage: System Account (r:7 w:7) + // Storage: System Account (r:6 w:6) // Storage: MarketCommons MarketPool (r:1 w:0) fn admin_move_market_to_resolved_scalar_disputed(r: u32, d: u32) -> Weight { - (132_066_000 as Weight) - // Standard Error: 1_000 - .saturating_add((120_000 as Weight).saturating_mul(r as Weight)) - // Standard Error: 21_000 - .saturating_add((30_950_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) + (79_803_000 as Weight) + // Standard Error: 4_000 + .saturating_add((34_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 63_000 + .saturating_add((21_525_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(d as Weight))) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) + .saturating_add(T::DbWeight::get().writes(4 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) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) // Storage: Balances Reserves (r:7 w:7) - // Storage: GlobalDisputes Winners (r:1 w:0) - // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) // 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 { - (227_185_000 as Weight) - // Standard Error: 6_000 - .saturating_add((69_000 as Weight).saturating_mul(r as Weight)) - // Standard Error: 90_000 - .saturating_add((33_824_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) + (92_016_000 as Weight) + // Standard Error: 21_000 + .saturating_add((258_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 301_000 + .saturating_add((23_377_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(6 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(5 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 MarketIdsForEdit (r:1 w:0) // Storage: Balances Reserves (r:1 w:1) fn approve_market() -> Weight { - (62_900_000 as Weight) + (41_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: MarketCommons Markets (r:1 w:0) // Storage: PredictionMarkets MarketIdsForEdit (r:1 w:1) fn request_edit(r: u32) -> Weight { - (37_307_000 as Weight) + (23_960_000 as Weight) // Standard Error: 0 - .saturating_add((3_000 as Weight).saturating_mul(r as Weight)) + .saturating_add((1_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -221,9 +219,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Tokens Accounts (r:2 w:2) // Storage: Tokens TotalIssuance (r:2 w:2) fn buy_complete_set(a: u32) -> Weight { - (63_624_000 as Weight) - // Standard Error: 12_000 - .saturating_add((26_565_000 as Weight).saturating_mul(a as Weight)) + (55_744_000 as Weight) + // Standard Error: 16_000 + .saturating_add((17_578_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -235,9 +233,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerCloseTimeFrame (r:1 w:1) // Storage: MarketCommons Markets (r:0 w:1) fn create_market(m: u32) -> Weight { - (75_202_000 as Weight) - // Standard Error: 3_000 - .saturating_add((53_000 as Weight).saturating_mul(m as Weight)) + (47_383_000 as Weight) + // Standard Error: 2_000 + .saturating_add((41_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -246,9 +244,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerCloseTimeFrame (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) fn edit_market(m: u32) -> Weight { - (64_080_000 as Weight) - // Standard Error: 0 - .saturating_add((117_000 as Weight).saturating_mul(m as Weight)) + (40_572_000 as Weight) + // Standard Error: 1_000 + .saturating_add((34_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -262,11 +260,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons MarketPool (r:1 w:1) // Storage: Swaps Pools (r:0 w:1) fn deploy_swap_pool_for_market_future_pool(a: u32, o: u32) -> Weight { - (108_283_000 as Weight) - // Standard Error: 14_000 - .saturating_add((42_613_000 as Weight).saturating_mul(a as Weight)) - // Standard Error: 13_000 - .saturating_add((322_000 as Weight).saturating_mul(o as Weight)) + (59_265_000 as Weight) + // Standard Error: 63_000 + .saturating_add((27_729_000 as Weight).saturating_mul(a as Weight)) + // Standard Error: 62_000 + .saturating_add((391_000 as Weight).saturating_mul(o as Weight)) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(7 as Weight)) @@ -281,32 +279,26 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons MarketPool (r:1 w:1) // Storage: Swaps Pools (r:0 w:1) fn deploy_swap_pool_for_market_open_pool(a: u32) -> Weight { - (136_673_000 as Weight) - // Standard Error: 16_000 - .saturating_add((42_795_000 as Weight).saturating_mul(a as Weight)) + (72_610_000 as Weight) + // Standard Error: 135_000 + .saturating_add((28_739_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(6 as Weight)) .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(a as Weight))) } - // Storage: MarketCommons Markets (r:1 w:0) - // Storage: PredictionMarkets Disputes (r:1 w:0) - // Storage: GlobalDisputes Winners (r:1 w:1) - // Storage: GlobalDisputes Outcomes (r:7 w:7) - // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:2 w:2) - fn start_global_dispute(_m: u32) -> Weight { - (143_932_000 as Weight) - .saturating_add(T::DbWeight::get().reads(12 as Weight)) - .saturating_add(T::DbWeight::get().writes(10 as Weight)) + fn start_global_dispute(m: u32) -> Weight { + (6_559_000 as Weight) + // Standard Error: 1_000 + .saturating_add((2_000 as Weight).saturating_mul(m as Weight)) } // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: MarketCommons Markets (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) - // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) - fn dispute_authorized(_d: u32) -> Weight { - (77_511_000 as Weight) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) + fn dispute_authorized() -> Weight { + (47_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) } // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) @@ -314,14 +306,10 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Balances Reserves (r:2 w:2) // Storage: System Account (r:2 w:2) // Storage: MarketCommons MarketPool (r:1 w:0) - fn resolve_failed_mdm_authorized_scalar(d: u32) -> Weight { - (80_390_000 as Weight) - // Standard Error: 25_000 - .saturating_add((20_931_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(d as Weight))) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(d as Weight))) + fn resolve_failed_mdm_authorized_scalar() -> Weight { + (109_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(8 as Weight)) + .saturating_add(T::DbWeight::get().writes(6 as Weight)) } // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) @@ -330,20 +318,16 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: System Account (r:2 w:2) // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: Swaps Pools (r:1 w:1) - fn resolve_failed_mdm_authorized_categorical(d: u32) -> Weight { - (103_383_000 as Weight) - // Standard Error: 31_000 - .saturating_add((20_787_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(5 as Weight)) - .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(d as Weight))) + fn resolve_failed_mdm_authorized_categorical() -> Weight { + (147_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) } // Storage: Balances Reserves (r:1 w:1) // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets MarketIdsForEdit (r:0 w:1) fn handle_expired_advised_market() -> Weight { - (61_850_000 as Weight) + (44_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -353,7 +337,7 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Swaps Pools (r:1 w:1) // Storage: MarketCommons Markets (r:1 w:1) fn internal_resolve_categorical_reported() -> Weight { - (172_370_000 as Weight) + (83_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -362,14 +346,12 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: Swaps Pools (r:1 w:1) // Storage: MarketCommons Markets (r:1 w:1) - // Storage: GlobalDisputes Winners (r:1 w:0) - // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) // Storage: System Account (r:1 w:1) fn internal_resolve_categorical_disputed(d: u32) -> Weight { - (183_852_000 as Weight) - // Standard Error: 82_000 - .saturating_add((24_286_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) + (89_440_000 as Weight) + // Standard Error: 295_000 + .saturating_add((16_181_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } // Storage: Balances Reserves (r:1 w:1) @@ -377,7 +359,7 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: MarketCommons Markets (r:1 w:1) fn internal_resolve_scalar_reported() -> Weight { - (73_231_000 as Weight) + (50_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -385,15 +367,12 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: MarketCommons Markets (r:1 w:1) - // Storage: GlobalDisputes Winners (r:1 w:0) - // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) - // Storage: System Account (r:1 w:1) fn internal_resolve_scalar_disputed(d: u32) -> Weight { - (90_052_000 as Weight) - // Standard Error: 74_000 - .saturating_add((21_265_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) + (56_385_000 as Weight) + // Standard Error: 131_000 + .saturating_add((15_225_000 as Weight).saturating_mul(d as Weight)) + .saturating_add(T::DbWeight::get().reads(4 as Weight)) + .saturating_add(T::DbWeight::get().writes(3 as Weight)) } // Storage: Timestamp Now (r:1 w:0) // Storage: PredictionMarkets MarketsCollectingSubsidy (r:1 w:1) @@ -405,15 +384,15 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerReportBlock (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) fn on_initialize_resolve_overhead() -> Weight { - (45_170_000 as Weight) + (30_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(9 as Weight)) .saturating_add(T::DbWeight::get().writes(8 as Weight)) } // Storage: PredictionMarkets MarketsCollectingSubsidy (r:1 w:1) fn process_subsidy_collecting_markets_raw(a: u32) -> Weight { - (5_577_000 as Weight) - // Standard Error: 8_000 - .saturating_add((507_000 as Weight).saturating_mul(a as Weight)) + (3_535_000 as Weight) + // Standard Error: 6_000 + .saturating_add((176_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -422,7 +401,7 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: System Account (r:1 w:1) // Storage: Tokens TotalIssuance (r:1 w:1) fn redeem_shares_categorical() -> Weight { - (130_241_000 as Weight) + (73_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -431,7 +410,7 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: System Account (r:1 w:1) // Storage: Tokens TotalIssuance (r:2 w:2) fn redeem_shares_scalar() -> Weight { - (144_640_000 as Weight) + (98_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -440,24 +419,20 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerCloseTimeFrame (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) // Storage: PredictionMarkets MarketIdsForEdit (r:0 w:1) - fn reject_market(c: u32, o: u32, r: u32) -> Weight { - (89_918_000 as Weight) - // Standard Error: 0 - .saturating_add((76_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 0 - .saturating_add((81_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 0 - .saturating_add((3_000 as Weight).saturating_mul(r as Weight)) + fn reject_market(c: u32, o: u32, _r: u32) -> Weight { + (60_929_000 as Weight) + // Standard Error: 1_000 + .saturating_add((8_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 1_000 + .saturating_add((15_000 as Weight).saturating_mul(o as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } // Storage: MarketCommons Markets (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) // Storage: PredictionMarkets MarketIdsPerReportBlock (r:1 w:1) - fn report(m: u32) -> Weight { - (50_223_000 as Weight) - // Standard Error: 0 - .saturating_add((16_000 as Weight).saturating_mul(m as Weight)) + fn report(_m: u32) -> Weight { + (31_154_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -466,9 +441,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Tokens Accounts (r:2 w:2) // Storage: Tokens TotalIssuance (r:2 w:2) fn sell_complete_set(a: u32) -> Weight { - (48_611_000 as Weight) + (44_770_000 as Weight) // Standard Error: 12_000 - .saturating_add((33_331_000 as Weight).saturating_mul(a as Weight)) + .saturating_add((21_432_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -481,9 +456,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketsCollectingSubsidy (r:1 w:1) // Storage: Swaps Pools (r:0 w:1) fn start_subsidy(a: u32) -> Weight { - (57_592_000 as Weight) - // Standard Error: 2_000 - .saturating_add((53_000 as Weight).saturating_mul(a as Weight)) + (34_382_000 as Weight) + // Standard Error: 1_000 + .saturating_add((36_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -491,11 +466,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons Markets (r:32 w:0) // Storage: PredictionMarkets MarketIdsPerOpenTimeFrame (r:1 w:1) fn market_status_manager(b: u32, f: u32) -> Weight { - (27_651_000 as Weight) - // Standard Error: 3_000 - .saturating_add((6_365_000 as Weight).saturating_mul(b as Weight)) - // Standard Error: 3_000 - .saturating_add((6_378_000 as Weight).saturating_mul(f as Weight)) + (7_909_000 as Weight) + // Standard Error: 10_000 + .saturating_add((4_309_000 as Weight).saturating_mul(b as Weight)) + // Standard Error: 10_000 + .saturating_add((4_287_000 as Weight).saturating_mul(f as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight))) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(f as Weight))) @@ -505,11 +480,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons Markets (r:32 w:0) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) fn market_resolution_manager(r: u32, d: u32) -> Weight { - (29_736_000 as Weight) - // Standard Error: 3_000 - .saturating_add((6_353_000 as Weight).saturating_mul(r as Weight)) - // Standard Error: 3_000 - .saturating_add((6_344_000 as Weight).saturating_mul(d as Weight)) + (8_808_000 as Weight) + // Standard Error: 11_000 + .saturating_add((4_290_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 11_000 + .saturating_add((4_285_000 as Weight).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight))) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(d as Weight))) @@ -517,7 +492,7 @@ impl WeightInfoZeitgeist for WeightInfo { } // Storage: PredictionMarkets MarketsCollectingSubsidy (r:1 w:1) fn process_subsidy_collecting_markets_dummy() -> Weight { - (5_470_000 as Weight) + (3_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } From 25d2cfda094b07904cd0f81187860fce7c7c263c Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 9 Dec 2022 09:52:51 +0100 Subject: [PATCH 43/93] down tracing-core to get try-runtime logs --- Cargo.lock | 10 +++++----- node/Cargo.toml | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d1d9ef5d7..58c21b4ac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -11373,9 +11373,9 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" [[package]] name = "tracing" -version = "0.1.37" +version = "0.1.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" +checksum = "5d0ecdcb44a79f0fe9844f0c4f33a342cbcbb5117de8001e6ba0dc2351327d09" dependencies = [ "cfg-if 1.0.0", "pin-project-lite 0.2.9", @@ -11396,11 +11396,11 @@ dependencies = [ [[package]] name = "tracing-core" -version = "0.1.30" +version = "0.1.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" +checksum = "f54c8ca710e81886d498c2fd3331b56c93aa248d49de2222ad2742247c60072f" dependencies = [ - "once_cell", + "lazy_static", "valuable", ] diff --git a/node/Cargo.toml b/node/Cargo.toml index 8c2287baf..a89fc7bbf 100644 --- a/node/Cargo.toml +++ b/node/Cargo.toml @@ -99,7 +99,7 @@ hex-literal = { version = "0.3.4" } jsonrpsee = { version = "0.14.0", features = ["server"] } log = { optional = true, version = "0.4.17" } # TODO(#865): Remove in future Polkadot release -tracing-core = "=0.1.30" +tracing-core = "=0.1.26" # Zeitgeist From 5e29644c0d7beff445e1168c5668cb6b6926260f Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 13 Dec 2022 12:52:46 +0100 Subject: [PATCH 44/93] rename failed to expired --- primitives/src/traits/dispute_api.rs | 9 +++---- zrml/authorized/src/lib.rs | 2 +- zrml/court/src/lib.rs | 2 +- zrml/prediction-markets/src/benchmarks.rs | 12 ++++----- zrml/prediction-markets/src/lib.rs | 33 ++++++++++++----------- zrml/prediction-markets/src/tests.rs | 8 +++--- zrml/prediction-markets/src/weights.rs | 12 ++++----- zrml/simple-disputes/src/lib.rs | 2 +- 8 files changed, 40 insertions(+), 40 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 43bd942ab..9e56410dc 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -64,13 +64,10 @@ pub trait DisputeApi { market: &Market, ) -> Result, DispatchError>; - /// Query if the dispute mechanism failed for a dispute market. + /// Returns `true` if the market dispute mechanism + /// was unable to come to a conclusion within a specified time. /// **May** assume that `market.dispute_mechanism` refers to the calling dispute API. - /// - /// # Returns - /// - /// Returns `true` if the dispute mechanism failed. Otherwise `false`. - fn is_fail( + fn is_expired( disputes: &[MarketDispute], market_id: &Self::MarketId, market: &Market, diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 63020550f..766511c4c 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -233,7 +233,7 @@ mod pallet { Ok(Self::get_auto_resolve(market_id)) } - fn is_fail( + fn is_expired( _: &[MarketDispute], market_id: &Self::MarketId, market: &Market>, diff --git a/zrml/court/src/lib.rs b/zrml/court/src/lib.rs index b2369bc37..bd2550e9e 100644 --- a/zrml/court/src/lib.rs +++ b/zrml/court/src/lib.rs @@ -569,7 +569,7 @@ mod pallet { Ok(None) } - fn is_fail( + fn is_expired( _: &[MarketDispute], _: &Self::MarketId, market: &Market>, diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index fcbf7a433..41241ae73 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -841,7 +841,7 @@ benchmarks! { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } - resolve_failed_mdm_authorized_scalar { + resolve_expired_mdm_authorized_scalar { let report_outcome = OutcomeReport::Scalar(u128::MAX); let (caller, market_id) = create_close_and_report_market::( MarketCreation::Permissionless, @@ -874,14 +874,14 @@ benchmarks! { now + authority_report_period.saturated_into() + 1u64.saturated_into() ); - let call = Call::::resolve_failed_mdm { market_id }; + let call = Call::::resolve_expired_mdm { market_id }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } verify { - assert_last_event::(Event::DisputeMechanismFailed::(market_id).into()); + assert_last_event::(Event::DisputeMechanismExpired::(market_id).into()); } - resolve_failed_mdm_authorized_categorical { + resolve_expired_mdm_authorized_categorical { let categories = T::MaxCategories::get(); let (caller, market_id) = setup_reported_categorical_market_with_pool::( @@ -912,11 +912,11 @@ benchmarks! { now + authority_report_period.saturated_into() + 1u64.saturated_into() ); - let call = Call::::resolve_failed_mdm { market_id }; + let call = Call::::resolve_expired_mdm { market_id }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } verify { - assert_last_event::(Event::DisputeMechanismFailed::(market_id).into()); + assert_last_event::(Event::DisputeMechanismExpired::(market_id).into()); } handle_expired_advised_market { diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index dcbe2341d..4d1d5af17 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -487,17 +487,18 @@ mod pallet { Ok((Some(T::WeightInfo::dispute_authorized())).into()) } - /// Resolve the market, when the dispute mechanism failed. + /// Resolve the market, + /// if the dispute mechanism was unable to come to a conclusion in a specified time. /// /// # Weight /// /// Complexity: `O(n)`, where `n` is the number of outstanding disputes. #[pallet::weight( - T::WeightInfo::resolve_failed_mdm_authorized_categorical() - .max(T::WeightInfo::resolve_failed_mdm_authorized_scalar()) + T::WeightInfo::resolve_expired_mdm_authorized_categorical() + .max(T::WeightInfo::resolve_expired_mdm_authorized_scalar()) )] #[transactional] - pub fn resolve_failed_mdm( + pub fn resolve_expired_mdm( origin: OriginFor, #[pallet::compact] market_id: MarketIdOf, ) -> DispatchResultWithPostInfo { @@ -506,25 +507,27 @@ mod pallet { ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); let disputes = Disputes::::get(market_id); // TODO(#782): use multiple benchmarks paths for different dispute mechanisms - let is_fail = match market.dispute_mechanism { + let is_expired = match market.dispute_mechanism { MarketDisputeMechanism::Authorized => { - T::Authorized::is_fail(&disputes, &market_id, &market)? + T::Authorized::is_expired(&disputes, &market_id, &market)? + } + MarketDisputeMechanism::Court => { + T::Court::is_expired(&disputes, &market_id, &market)? } - MarketDisputeMechanism::Court => T::Court::is_fail(&disputes, &market_id, &market)?, MarketDisputeMechanism::SimpleDisputes => { - T::SimpleDisputes::is_fail(&disputes, &market_id, &market)? + T::SimpleDisputes::is_expired(&disputes, &market_id, &market)? } }; - ensure!(is_fail, Error::::DisputeMechanismNotFailed); + ensure!(is_expired, Error::::DisputeMechanismNotExpired); Self::on_resolution(&market_id, &market)?; - Self::deposit_event(Event::DisputeMechanismFailed(market_id)); + Self::deposit_event(Event::DisputeMechanismExpired(market_id)); let weight = match market.market_type { - MarketType::Scalar(_) => T::WeightInfo::resolve_failed_mdm_authorized_scalar(), + MarketType::Scalar(_) => T::WeightInfo::resolve_expired_mdm_authorized_scalar(), MarketType::Categorical(_) => { - T::WeightInfo::resolve_failed_mdm_authorized_categorical() + T::WeightInfo::resolve_expired_mdm_authorized_categorical() } }; @@ -1535,7 +1538,7 @@ mod pallet { /// registered on-chain. CannotDisputeSameOutcome, /// The market dispute mechanism has not failed. - DisputeMechanismNotFailed, + DisputeMechanismNotExpired, /// Only creator is able to edit the market. EditorNotCreator, /// EditReason's length greater than MaxEditReasonLen. @@ -1636,8 +1639,8 @@ mod pallet { BadOnInitialize, /// A complete set of assets has been bought \[market_id, amount_per_asset, buyer\] BoughtCompleteSet(MarketIdOf, BalanceOf, ::AccountId), - /// A market dispute mechansim failed \[market_id\] - DisputeMechanismFailed(MarketIdOf), + /// A market dispute mechansim has expired \[market_id\] + DisputeMechanismExpired(MarketIdOf), /// A market has been approved \[market_id, new_market_status\] MarketApproved(MarketIdOf, MarketStatus), /// A market has been created \[market_id, market_account, market\] diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 688ba8cf3..7fb143790 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2326,7 +2326,7 @@ fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { assert_eq!(disputes.len(), 1); run_blocks(::ReportPeriod::get() + 1); - assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), 0)); + assert_ok!(PredictionMarkets::resolve_expired_mdm(Origin::signed(FRED), 0)); let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); @@ -3179,13 +3179,13 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { run_blocks(::ReportPeriod::get()); assert_noop!( - PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id), - Error::::DisputeMechanismNotFailed + PredictionMarkets::resolve_expired_mdm(Origin::signed(FRED), market_id), + Error::::DisputeMechanismNotExpired ); run_blocks(1); // ReportPeriod is now over - assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id)); + assert_ok!(PredictionMarkets::resolve_expired_mdm(Origin::signed(FRED), market_id)); let market_after = MarketCommons::market(&market_id).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index 16abf40e8..683f47367 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -61,8 +61,8 @@ pub trait WeightInfoZeitgeist { fn deploy_swap_pool_for_market_open_pool(a: u32) -> Weight; fn start_global_dispute(m: u32) -> Weight; fn dispute_authorized() -> Weight; - fn resolve_failed_mdm_authorized_scalar() -> Weight; - fn resolve_failed_mdm_authorized_categorical() -> Weight; + fn resolve_expired_mdm_authorized_scalar() -> Weight; + fn resolve_expired_mdm_authorized_categorical() -> Weight; fn handle_expired_advised_market() -> Weight; fn internal_resolve_categorical_reported() -> Weight; fn internal_resolve_categorical_disputed(d: u32) -> Weight; @@ -306,8 +306,8 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Balances Reserves (r:2 w:2) // Storage: System Account (r:2 w:2) // Storage: MarketCommons MarketPool (r:1 w:0) - fn resolve_failed_mdm_authorized_scalar() -> Weight { - (109_000_000 as Weight) + fn resolve_expired_mdm_authorized_scalar() -> Weight { + (105_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().writes(6 as Weight)) } @@ -318,8 +318,8 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: System Account (r:2 w:2) // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: Swaps Pools (r:1 w:1) - fn resolve_failed_mdm_authorized_categorical() -> Weight { - (147_000_000 as Weight) + fn resolve_expired_mdm_authorized_categorical() -> Weight { + (135_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(9 as Weight)) .saturating_add(T::DbWeight::get().writes(7 as Weight)) } diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index 1be98446d..0a45c318e 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -181,7 +181,7 @@ mod pallet { Ok(Self::get_auto_resolve(disputes, market)) } - fn is_fail( + fn is_expired( _: &[MarketDispute], _: &Self::MarketId, market: &Market>, From fbf45abd30b2df8ae845680a4b2d33001a2b8aee Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 13 Dec 2022 13:01:58 +0100 Subject: [PATCH 45/93] rename resolution to resolve_at --- primitives/src/traits/dispute_api.rs | 4 ++-- zrml/authorized/src/mock.rs | 4 ++-- zrml/court/src/mock.rs | 4 ++-- zrml/simple-disputes/src/mock.rs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 9e56410dc..560346b7a 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -100,7 +100,7 @@ pub trait DisputeResolutionApi { /// Returns the number of elements in the storage structure. fn add_auto_resolve( market_id: &Self::MarketId, - resolution: Self::BlockNumber, + resolve_at: Self::BlockNumber, ) -> Result; /// Remove a future block resolution of a disputed market. @@ -108,5 +108,5 @@ pub trait DisputeResolutionApi { /// # Returns /// /// Returns the number of elements in the storage structure. - fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber) -> u32; + fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32; } diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 7113274a3..59c4b1926 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -81,12 +81,12 @@ impl DisputeResolutionApi for NoopResolution { fn add_auto_resolve( _market_id: &Self::MarketId, - _resolution: Self::BlockNumber, + _resolve_at: Self::BlockNumber, ) -> Result { Ok(0u32) } - fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) -> u32 { + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { 0u32 } } diff --git a/zrml/court/src/mock.rs b/zrml/court/src/mock.rs index 567a40af1..27b47da00 100644 --- a/zrml/court/src/mock.rs +++ b/zrml/court/src/mock.rs @@ -84,12 +84,12 @@ impl DisputeResolutionApi for NoopResolution { fn add_auto_resolve( _market_id: &Self::MarketId, - _resolution: Self::BlockNumber, + _resolve_at: Self::BlockNumber, ) -> Result { Ok(0u32) } - fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) -> u32 { + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { 0u32 } } diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index 163ab57d1..a3db7fac0 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -71,12 +71,12 @@ impl DisputeResolutionApi for NoopResolution { fn add_auto_resolve( _market_id: &Self::MarketId, - _resolution: Self::BlockNumber, + _resolve_at: Self::BlockNumber, ) -> Result { Ok(0u32) } - fn remove_auto_resolve(_market_id: &Self::MarketId, _resolution: Self::BlockNumber) -> u32 { + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { 0u32 } } From b038a96e44a51ca30daa92755c2e1cd05dba0b16 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 13 Dec 2022 13:09:21 +0100 Subject: [PATCH 46/93] fix small nitpicks --- runtime/common/src/lib.rs | 4 ++-- zrml/authorized/src/lib.rs | 4 +--- zrml/prediction-markets/src/migrations.rs | 6 +++--- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 96228b053..6de0e466a 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -61,7 +61,7 @@ macro_rules! decl_common_types { ( zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, zrml_prediction_markets::migrations::AddFieldToAuthorityReport, - ) + ), >; #[cfg(not(feature = "parachain"))] @@ -74,7 +74,7 @@ macro_rules! decl_common_types { ( zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, zrml_prediction_markets::migrations::AddFieldToAuthorityReport, - ) + ), >; pub type Header = generic::Header; diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 766511c4c..8fda85f82 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -71,7 +71,7 @@ mod pallet { #[frame_support::transactional] #[pallet::weight(T::WeightInfo::authorize_market_outcome( CacheSize::get(), - CacheSize::get() + CacheSize::get(), ))] pub fn authorize_market_outcome( origin: OriginFor, @@ -138,8 +138,6 @@ mod pallet { #[pallet::error] pub enum Error { - /// An unauthorized account attempts to submit a report. - NotAuthorizedForThisMarket, /// The market unexpectedly has the incorrect dispute mechanism. MarketDoesNotHaveDisputeMechanismAuthorized, /// An account attempts to submit a report to an undisputed market. diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 75a7dbb02..6a70276e7 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -60,7 +60,7 @@ impl OnRuntim let prediction_markets_version = StorageVersion::get::>(); if prediction_markets_version != PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION { log::info!( - "prediction-markets version is {:?}, require {:?}", + "UpdateMarketIdsPerDisputeBlock: prediction-markets version is {:?}, require {:?}", prediction_markets_version, PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION, ); @@ -106,9 +106,9 @@ impl OnRuntim } let now = >::block_number(); + let mut resolve_at = + now.saturating_add(::ReportPeriod::get()); for id in authorized_ids { - let mut resolve_at: T::BlockNumber = - now.saturating_add(::ReportPeriod::get()); let mut ids = crate::MarketIdsPerDisputeBlock::::get(resolve_at); total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); From a948faaaf5d631ab55c36ef7dc00ddf91ab70393 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 13 Dec 2022 13:17:51 +0100 Subject: [PATCH 47/93] edit doc comment --- zrml/authorized/src/lib.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 8fda85f82..125489c80 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -102,7 +102,8 @@ mod pallet { #[pallet::config] pub trait Config: frame_system::Config { - /// The period in which the authority has to report. + /// The period in which the authority has to report. This value must not be zero. + /// This value should be fairly large, so that the authority has enough time to report. #[pallet::constant] type ReportPeriod: Get; From 30ce824080b7b38cde00b68331da73fee553d34f Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 13 Dec 2022 13:43:40 +0100 Subject: [PATCH 48/93] use reporting period from last dispute --- zrml/authorized/src/lib.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 125489c80..361d63a31 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -233,7 +233,7 @@ mod pallet { } fn is_expired( - _: &[MarketDispute], + disputes: &[MarketDispute], market_id: &Self::MarketId, market: &Market>, ) -> Result { @@ -241,10 +241,10 @@ mod pallet { market.dispute_mechanism == MarketDisputeMechanism::Authorized, Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); + let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); - let report = market.report.as_ref().ok_or(Error::::MarketIsNotReported)?; let now = frame_system::Pallet::::block_number(); - let is_expired = report.at.saturating_add(T::ReportPeriod::get()) < now; + let is_expired = last_dispute.at.saturating_add(T::ReportPeriod::get()) < now; Ok(is_unreported && is_expired) } } From d539bf6a7b0576ba5cc7e9a2233b3c8c508740d5 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 13 Dec 2022 13:48:29 +0100 Subject: [PATCH 49/93] modify doc string --- zrml/authorized/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 361d63a31..e4e941f72 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -111,6 +111,7 @@ mod pallet { type Event: From> + IsType<::Event>; /// The period, in which the authority can correct the outcome of a market. + /// This value must not be zero. #[pallet::constant] type CorrectionPeriod: Get; From a99b8bc0a563703163096594e1ee22c91953932c Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 13 Dec 2022 14:25:27 +0100 Subject: [PATCH 50/93] document private authorozed api --- zrml/authorized/src/lib.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index e4e941f72..f4743516c 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -168,10 +168,13 @@ mod pallet { where T: Config, { + /// Return the resolution block number for the given market. fn get_auto_resolve(market_id: &MarketIdOf) -> Option { AuthorizedOutcomeReports::::get(market_id).map(|report| report.resolve_at) } + /// Return the number of elements from the vector implied by the `remove_auto_resolve` call. + /// This is especially useful to calculate a proper weight. fn remove_auto_resolve(market_id: &MarketIdOf) -> u32 { if let Some(resolve_at) = Self::get_auto_resolve(market_id) { T::DisputeResolution::remove_auto_resolve(market_id, resolve_at) From 846d926f928baef569207849b45e8f4c6b65569a Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 07:26:41 +0100 Subject: [PATCH 51/93] fix after merge --- zrml/prediction-markets/src/benchmarks.rs | 6 +++--- zrml/prediction-markets/src/lib.rs | 2 +- zrml/prediction-markets/src/migrations.rs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 1d41f7ae7..bb652c243 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -822,12 +822,12 @@ benchmarks! { report_outcome, )?; - ::MarketCommons::mutate_market(&market_id, |market| { + >::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - let market = ::MarketCommons::market(&market_id)?; + let market = >::market(&market_id)?; if let MarketType::Scalar(range) = market.market_type { assert!(1u128 < *range.end()); } else { @@ -889,7 +889,7 @@ benchmarks! { OutcomeReport::Categorical(0u16) )?; - ::MarketCommons::mutate_market(&market_id, |market| { + >::mutate_market(&market_id, |market| { market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 74d4fe0f5..5c8e78e47 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -502,7 +502,7 @@ mod pallet { #[pallet::compact] market_id: MarketIdOf, ) -> DispatchResultWithPostInfo { ensure_signed(origin)?; - let market = T::MarketCommons::market(&market_id)?; + let market = >::market(&market_id)?; ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); let disputes = Disputes::::get(market_id); // TODO(#782): use multiple benchmarks paths for different dispute mechanisms diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 6a70276e7..eb447f252 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -77,7 +77,7 @@ impl OnRuntim total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); bounded_vec.retain(|id| { - if let Ok(market) = ::MarketCommons::market(id) { + if let Ok(market) = >::market(id) { match market.dispute_mechanism { MarketDisputeMechanism::Authorized => { authorized_ids.push(*id); From 8a8c4b954b3f7ca1f215edc4f99ef5cf44d559df Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 08:00:20 +0100 Subject: [PATCH 52/93] print market id for try-runtime tests --- zrml/prediction-markets/src/migrations.rs | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index eb447f252..c7a536777 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -406,16 +406,20 @@ impl OnRuntim AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, ) { + let key_str = format!("{:?}", key.as_slice()); if let Some(AuthorityReport { resolve_at: _, outcome }) = new_value { - let old_value: Option = - Self::get_temp_storage(&format!("{:?}", key.as_slice())) - .expect("old value not found"); + let old_value: Option = Self::get_temp_storage(&key_str) + .unwrap_or_else(|| panic!("old value not found for market id {:?}", key_str)); assert_eq!(old_value.unwrap(), outcome); markets_count += 1_u32; } else { - panic!("storage iter should only find present (Option::Some) values"); + panic!( + "For market id {:?} storage iter should only find present (Option::Some) \ + values", + key_str + ); } } let old_markets_count: u32 = From 346d892b330220dbfac784de7236981b9f341a7d Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 08:05:42 +0100 Subject: [PATCH 53/93] bump migration versions --- zrml/prediction-markets/src/migrations.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index c7a536777..cb6198f48 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -36,15 +36,15 @@ const PREDICTION_MARKETS: &[u8] = b"PredictionMarkets"; const MARKET_IDS_PER_DISPUTE_BLOCK: &[u8] = b"MarketIdsPerDisputeBlock"; // TODO increase storage versions here, when last migration was executed -const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 5; -const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 6; +const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 6; +const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 7; const AUTHORIZED: &[u8] = b"Authorized"; const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; // TODO increase storage versions here, when last migration was executed -const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 1; -const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 2; +const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; +const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); From 0c00e8f5a48abaac432b95f193eef0ead37b6053 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 08:22:06 +0100 Subject: [PATCH 54/93] avoid storage_iter --- zrml/prediction-markets/src/migrations.rs | 25 +++++++---------------- 1 file changed, 7 insertions(+), 18 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index cb6198f48..8c93d20a4 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -15,15 +15,16 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{CacheSize, Config, MarketIdOf, Pallet}; -use alloc::{string::ToString, vec::Vec}; +use crate::{Config, Pallet}; +#[cfg(feature = "try-runtime")] +use alloc::string::ToString; +use alloc::vec::Vec; use frame_support::{ dispatch::Weight, log, migration::{put_storage_value, storage_iter}, pallet_prelude::PhantomData, traits::{Get, OnRuntimeUpgrade, StorageVersion}, - BoundedVec, }; #[cfg(feature = "try-runtime")] use scale_info::prelude::format; @@ -32,17 +33,12 @@ use zeitgeist_primitives::types::{AuthorityReport, MarketDisputeMechanism, Outco use zrml_authorized::Pallet as AuthorizedPallet; use zrml_market_commons::MarketCommonsPalletApi; -const PREDICTION_MARKETS: &[u8] = b"PredictionMarkets"; -const MARKET_IDS_PER_DISPUTE_BLOCK: &[u8] = b"MarketIdsPerDisputeBlock"; - -// TODO increase storage versions here, when last migration was executed const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 6; const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 7; const AUTHORIZED: &[u8] = b"Authorized"; const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; -// TODO increase storage versions here, when last migration was executed const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; @@ -70,10 +66,7 @@ impl OnRuntim let mut new_storage_map = Vec::new(); let mut authorized_ids = Vec::new(); - for (key, mut bounded_vec) in storage_iter::, CacheSize>>( - PREDICTION_MARKETS, - MARKET_IDS_PER_DISPUTE_BLOCK, - ) { + for (key, mut bounded_vec) in crate::MarketIdsPerDisputeBlock::::iter() { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); bounded_vec.retain(|id| { @@ -96,12 +89,7 @@ impl OnRuntim } for (key, new_bounded_vec) in new_storage_map { - put_storage_value::, CacheSize>>( - PREDICTION_MARKETS, - MARKET_IDS_PER_DISPUTE_BLOCK, - &key, - new_bounded_vec, - ); + crate::MarketIdsPerDisputeBlock::::insert(key, new_bounded_vec); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } @@ -148,6 +136,7 @@ mod tests_auto_resolution { mock::{ExtBuilder, Runtime}, MomentOf, }; + use frame_support::BoundedVec; use zeitgeist_primitives::types::{ Deadlines, MarketCreation, MarketDisputeMechanism, MarketId, MarketPeriod, MarketStatus, MarketType, OutcomeReport, Report, ScoringRule, From e8761d2144d49a751239f4e5c241bc77d17bb25f Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 08:24:19 +0100 Subject: [PATCH 55/93] add warning --- zrml/prediction-markets/src/migrations.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 8c93d20a4..9286d76b4 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -80,6 +80,7 @@ impl OnRuntim MarketDisputeMechanism::SimpleDisputes => true, } } else { + log::warn!("UpdateMarketIdsPerDisputeBlock: Market id {:?} not found!", id); // no market for id in MarketIdsPerDisputeBlock false } From ac8a7e59601cb1dcc383562f5a0f824dbbf30173 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 09:30:59 +0100 Subject: [PATCH 56/93] set block number non-zero in migration test --- zrml/prediction-markets/src/migrations.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 9286d76b4..5f36338a5 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -170,6 +170,8 @@ mod tests_auto_resolution { Markets::::insert(market_id, market); + >::set_block_number(42u32.into()); + let now = >::block_number(); crate::MarketIdsPerDisputeBlock::::insert( now, From e6037880fbc77e480edddc7c5331c0020a3b30fd Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 09:55:40 +0100 Subject: [PATCH 57/93] move storage migration --- runtime/common/src/lib.rs | 4 +- zrml/authorized/src/migrations.rs | 257 ++++++++++++++++++++++ zrml/prediction-markets/src/migrations.rs | 195 +--------------- 3 files changed, 260 insertions(+), 196 deletions(-) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 76d2a17cb..5bbb934cf 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -60,7 +60,7 @@ macro_rules! decl_common_types { AllPalletsWithSystem, ( zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, - zrml_prediction_markets::migrations::AddFieldToAuthorityReport, + zrml_authorized::migrations::AddFieldToAuthorityReport, ), >; @@ -73,7 +73,7 @@ macro_rules! decl_common_types { AllPalletsWithSystem, ( zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, - zrml_prediction_markets::migrations::AddFieldToAuthorityReport, + zrml_authorized::migrations::AddFieldToAuthorityReport, ), >; diff --git a/zrml/authorized/src/migrations.rs b/zrml/authorized/src/migrations.rs index 16887b73b..bee4a8189 100644 --- a/zrml/authorized/src/migrations.rs +++ b/zrml/authorized/src/migrations.rs @@ -14,3 +14,260 @@ // // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . + +use crate::{Config, Pallet}; +#[cfg(feature = "try-runtime")] +use alloc::string::ToString; +use alloc::vec::Vec; +use frame_support::{ + dispatch::Weight, + log, + migration::{put_storage_value, storage_iter}, + pallet_prelude::PhantomData, + traits::{Get, OnRuntimeUpgrade, StorageVersion}, +}; +#[cfg(feature = "try-runtime")] +use scale_info::prelude::format; +use sp_runtime::traits::Saturating; +use zeitgeist_primitives::types::{AuthorityReport, OutcomeReport}; + +const AUTHORIZED: &[u8] = b"Authorized"; +const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; + +const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; +const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; + +pub struct AddFieldToAuthorityReport(PhantomData); + +// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. +impl OnRuntimeUpgrade for AddFieldToAuthorityReport { + fn on_runtime_upgrade() -> Weight + where + T: Config, + { + let mut total_weight = T::DbWeight::get().reads(1); + let authorized_version = StorageVersion::get::>(); + if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION { + log::info!( + "AddFieldToAuthorityReport: authorized version is {:?}, require {:?};", + authorized_version, + AUTHORIZED_REQUIRED_STORAGE_VERSION, + ); + return total_weight; + } + log::info!("AddFieldToAuthorityReport: Starting..."); + + let mut new_storage_map = Vec::new(); + let now = >::block_number(); + for (key, old_value) in + storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) + { + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + + if let Some(outcome) = old_value { + let resolve_at: T::BlockNumber = + now.saturating_add(::ReportPeriod::get()); + let new_value = AuthorityReport { resolve_at, outcome }; + new_storage_map.push((key, new_value)); + } + } + + for (key, new_value) in new_storage_map { + put_storage_value::>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &key, + Some(new_value), + ); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + } + + StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + log::info!("AddFieldToAuthorityReport: Done!"); + total_weight + } + + #[cfg(feature = "try-runtime")] + fn pre_upgrade() -> Result<(), &'static str> { + use frame_support::traits::OnRuntimeUpgradeHelpersExt; + let counter_key = "counter_key".to_string(); + Self::set_temp_storage(0_u32, &counter_key); + for (key, value) in + storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) + { + Self::set_temp_storage(value, &format!("{:?}", key.as_slice())); + + let counter: u32 = + Self::get_temp_storage(&counter_key).expect("counter key storage not found"); + Self::set_temp_storage(counter + 1_u32, &counter_key); + } + Ok(()) + } + + #[cfg(feature = "try-runtime")] + fn post_upgrade() -> Result<(), &'static str> { + use frame_support::traits::OnRuntimeUpgradeHelpersExt; + let mut markets_count = 0_u32; + let old_counter_key = "counter_key".to_string(); + for (key, new_value) in storage_iter::>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + ) { + let key_str = format!("{:?}", key.as_slice()); + if let Some(AuthorityReport { resolve_at: _, outcome }) = new_value { + let old_value: Option = Self::get_temp_storage(&key_str) + .unwrap_or_else(|| panic!("old value not found for market id {:?}", key_str)); + + assert_eq!(old_value.unwrap(), outcome); + + markets_count += 1_u32; + } else { + panic!( + "For market id {:?} storage iter should only find present (Option::Some) \ + values", + key_str + ); + } + } + let old_markets_count: u32 = + Self::get_temp_storage(&old_counter_key).expect("old counter key storage not found"); + assert_eq!(markets_count, old_markets_count); + Ok(()) + } +} + +#[cfg(test)] +mod tests_authorized { + use super::*; + use crate::mock::{ExtBuilder, Runtime}; + use frame_support::Twox64Concat; + use zeitgeist_primitives::types::{MarketId, OutcomeReport}; + + #[test] + fn on_runtime_upgrade_increments_the_storage_versions() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + AddFieldToAuthorityReport::::on_runtime_upgrade(); + let authorized_version = StorageVersion::get::>(); + assert_eq!(authorized_version, AUTHORIZED_NEXT_STORAGE_VERSION); + }); + } + + #[test] + fn on_runtime_sets_new_struct_with_resolve_at() { + ExtBuilder::default().build().execute_with(|| { + set_up_chain(); + + >::set_block_number(10_000); + + let hash = crate::migrations::utility::key_to_hash::(0); + let outcome = OutcomeReport::Categorical(42u16); + put_storage_value::>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &hash, + Some(outcome.clone()), + ); + + AddFieldToAuthorityReport::::on_runtime_upgrade(); + + let now = >::block_number(); + let resolve_at: ::BlockNumber = + now.saturating_add(::ReportPeriod::get()); + let expected = Some(AuthorityReport { resolve_at, outcome }); + + let actual = frame_support::migration::get_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) + .unwrap(); + assert_eq!(expected, actual); + }); + } + + #[test] + fn on_runtime_is_noop_if_versions_are_not_correct() { + ExtBuilder::default().build().execute_with(|| { + // storage migration already executed (storage version is incremented already) + StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); + + let hash = crate::migrations::utility::key_to_hash::(0); + let outcome = OutcomeReport::Categorical(42u16); + let now = >::block_number(); + let resolve_at: ::BlockNumber = + now.saturating_add(::ReportPeriod::get()); + let report = AuthorityReport { resolve_at, outcome }; + put_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, Some(report.clone())); + + AddFieldToAuthorityReport::::on_runtime_upgrade(); + + let actual = frame_support::migration::get_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) + .unwrap(); + assert_eq!(Some(report), actual); + }); + } + + fn set_up_chain() { + StorageVersion::new(AUTHORIZED_REQUIRED_STORAGE_VERSION).put::>(); + } +} + +// We use these utilities to prevent having to make the swaps pallet a dependency of +// prediciton-markets. The calls are based on the implementation of `StorageVersion`, found here: +// https://github.com/paritytech/substrate/blob/bc7a1e6c19aec92bfa247d8ca68ec63e07061032/frame/support/src/traits/metadata.rs#L168-L230 +// and previous migrations. +mod utility { + use crate::{BalanceOf, Config, MarketIdOf}; + use alloc::vec::Vec; + use frame_support::{ + migration::{get_storage_value, put_storage_value}, + storage::{storage_prefix, unhashed}, + traits::StorageVersion, + Blake2_128Concat, StorageHasher, + }; + use parity_scale_codec::Encode; + use zeitgeist_primitives::types::{Pool, PoolId}; + + #[allow(unused)] + const SWAPS: &[u8] = b"Swaps"; + #[allow(unused)] + const POOLS: &[u8] = b"Pools"; + #[allow(unused)] + fn storage_prefix_of_swaps_pallet() -> [u8; 32] { + storage_prefix(b"Swaps", b":__STORAGE_VERSION__:") + } + #[allow(unused)] + pub fn key_to_hash(key: K) -> Vec + where + H: StorageHasher, + K: Encode, + { + key.using_encoded(H::hash).as_ref().to_vec() + } + #[allow(unused)] + pub fn get_on_chain_storage_version_of_swaps_pallet() -> StorageVersion { + let key = storage_prefix_of_swaps_pallet(); + unhashed::get_or_default(&key) + } + #[allow(unused)] + pub fn put_storage_version_of_swaps_pallet(value: u16) { + let key = storage_prefix_of_swaps_pallet(); + unhashed::put(&key, &StorageVersion::new(value)); + } + #[allow(unused)] + pub fn get_pool(pool_id: PoolId) -> Option, MarketIdOf>> { + let hash = key_to_hash::(pool_id); + let pool_maybe = + get_storage_value::, MarketIdOf>>>(SWAPS, POOLS, &hash); + pool_maybe.unwrap_or(None) + } + #[allow(unused)] + pub fn set_pool(pool_id: PoolId, pool: Pool, MarketIdOf>) { + let hash = key_to_hash::(pool_id); + put_storage_value(SWAPS, POOLS, &hash, Some(pool)); + } +} diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 5f36338a5..02a0b585b 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -16,32 +16,20 @@ // along with Zeitgeist. If not, see . use crate::{Config, Pallet}; -#[cfg(feature = "try-runtime")] -use alloc::string::ToString; use alloc::vec::Vec; use frame_support::{ dispatch::Weight, log, - migration::{put_storage_value, storage_iter}, pallet_prelude::PhantomData, traits::{Get, OnRuntimeUpgrade, StorageVersion}, }; -#[cfg(feature = "try-runtime")] -use scale_info::prelude::format; use sp_runtime::traits::{One, Saturating}; -use zeitgeist_primitives::types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}; -use zrml_authorized::Pallet as AuthorizedPallet; +use zeitgeist_primitives::types::MarketDisputeMechanism; use zrml_market_commons::MarketCommonsPalletApi; const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 6; const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 7; -const AUTHORIZED: &[u8] = b"Authorized"; -const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; - -const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; -const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; - pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); // Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` @@ -319,187 +307,6 @@ mod tests_auto_resolution { } } -pub struct AddFieldToAuthorityReport(PhantomData); - -// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. -impl OnRuntimeUpgrade - for AddFieldToAuthorityReport -{ - fn on_runtime_upgrade() -> Weight - where - T: Config, - { - let mut total_weight = T::DbWeight::get().reads(1); - let authorized_version = StorageVersion::get::>(); - if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION { - log::info!( - "AddFieldToAuthorityReport: authorized version is {:?}, require {:?};", - authorized_version, - AUTHORIZED_REQUIRED_STORAGE_VERSION, - ); - return total_weight; - } - log::info!("AddFieldToAuthorityReport: Starting..."); - - let mut new_storage_map = Vec::new(); - let now = >::block_number(); - for (key, old_value) in - storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) - { - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - - if let Some(outcome) = old_value { - let resolve_at: T::BlockNumber = - now.saturating_add(::ReportPeriod::get()); - let new_value = AuthorityReport { resolve_at, outcome }; - new_storage_map.push((key, new_value)); - } - } - - for (key, new_value) in new_storage_map { - put_storage_value::>>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - &key, - Some(new_value), - ); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - } - - StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::info!("AddFieldToAuthorityReport: Done!"); - total_weight - } - - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result<(), &'static str> { - use frame_support::traits::OnRuntimeUpgradeHelpersExt; - let counter_key = "counter_key".to_string(); - Self::set_temp_storage(0_u32, &counter_key); - for (key, value) in - storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) - { - Self::set_temp_storage(value, &format!("{:?}", key.as_slice())); - - let counter: u32 = - Self::get_temp_storage(&counter_key).expect("counter key storage not found"); - Self::set_temp_storage(counter + 1_u32, &counter_key); - } - Ok(()) - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade() -> Result<(), &'static str> { - use frame_support::traits::OnRuntimeUpgradeHelpersExt; - let mut markets_count = 0_u32; - let old_counter_key = "counter_key".to_string(); - for (key, new_value) in storage_iter::>>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - ) { - let key_str = format!("{:?}", key.as_slice()); - if let Some(AuthorityReport { resolve_at: _, outcome }) = new_value { - let old_value: Option = Self::get_temp_storage(&key_str) - .unwrap_or_else(|| panic!("old value not found for market id {:?}", key_str)); - - assert_eq!(old_value.unwrap(), outcome); - - markets_count += 1_u32; - } else { - panic!( - "For market id {:?} storage iter should only find present (Option::Some) \ - values", - key_str - ); - } - } - let old_markets_count: u32 = - Self::get_temp_storage(&old_counter_key).expect("old counter key storage not found"); - assert_eq!(markets_count, old_markets_count); - Ok(()) - } -} - -#[cfg(test)] -mod tests_authorized { - use super::*; - use crate::mock::{ExtBuilder, Runtime}; - use frame_support::Twox64Concat; - use zeitgeist_primitives::types::{MarketId, OutcomeReport}; - - #[test] - fn on_runtime_upgrade_increments_the_storage_versions() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - AddFieldToAuthorityReport::::on_runtime_upgrade(); - let authorized_version = StorageVersion::get::>(); - assert_eq!(authorized_version, AUTHORIZED_NEXT_STORAGE_VERSION); - }); - } - - #[test] - fn on_runtime_sets_new_struct_with_resolve_at() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - - >::set_block_number(10_000); - - let hash = crate::migrations::utility::key_to_hash::(0); - let outcome = OutcomeReport::Categorical(42u16); - put_storage_value::>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - &hash, - Some(outcome.clone()), - ); - - AddFieldToAuthorityReport::::on_runtime_upgrade(); - - let now = >::block_number(); - let resolve_at: ::BlockNumber = - now.saturating_add(::ReportPeriod::get()); - let expected = Some(AuthorityReport { resolve_at, outcome }); - - let actual = frame_support::migration::get_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) - .unwrap(); - assert_eq!(expected, actual); - }); - } - - #[test] - fn on_runtime_is_noop_if_versions_are_not_correct() { - ExtBuilder::default().build().execute_with(|| { - // storage migration already executed (storage version is incremented already) - StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - - let hash = crate::migrations::utility::key_to_hash::(0); - let outcome = OutcomeReport::Categorical(42u16); - let now = >::block_number(); - let resolve_at: ::BlockNumber = - now.saturating_add(::ReportPeriod::get()); - let report = AuthorityReport { resolve_at, outcome }; - put_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, Some(report.clone())); - - AddFieldToAuthorityReport::::on_runtime_upgrade(); - - let actual = frame_support::migration::get_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) - .unwrap(); - assert_eq!(Some(report), actual); - }); - } - - fn set_up_chain() { - StorageVersion::new(AUTHORIZED_REQUIRED_STORAGE_VERSION).put::>(); - } -} - // We use these utilities to prevent having to make the swaps pallet a dependency of // prediciton-markets. The calls are based on the implementation of `StorageVersion`, found here: // https://github.com/paritytech/substrate/blob/bc7a1e6c19aec92bfa247d8ca68ec63e07061032/frame/support/src/traits/metadata.rs#L168-L230 From 1812e190735388d069a6a53e063941692d62728f Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 10:03:22 +0100 Subject: [PATCH 58/93] recalc migration markets counter --- zrml/authorized/src/migrations.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/zrml/authorized/src/migrations.rs b/zrml/authorized/src/migrations.rs index bee4a8189..8892abb4b 100644 --- a/zrml/authorized/src/migrations.rs +++ b/zrml/authorized/src/migrations.rs @@ -91,17 +91,17 @@ impl OnRuntimeUpgrade for AddFieldToAut #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { use frame_support::traits::OnRuntimeUpgradeHelpersExt; - let counter_key = "counter_key".to_string(); - Self::set_temp_storage(0_u32, &counter_key); + + let mut counter = 0_u32; for (key, value) in storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { Self::set_temp_storage(value, &format!("{:?}", key.as_slice())); - let counter: u32 = - Self::get_temp_storage(&counter_key).expect("counter key storage not found"); - Self::set_temp_storage(counter + 1_u32, &counter_key); + counter = counter.saturating_add(1_u32); } + let counter_key = "counter_key".to_string(); + Self::set_temp_storage(counter, &counter_key); Ok(()) } From 5fbec3472ca56a4e82b33e64eb67741374b7b996 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 10:25:04 +0100 Subject: [PATCH 59/93] abstract remove auto resolve --- zrml/prediction-markets/src/lib.rs | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 5c8e78e47..94f23f213 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -2019,14 +2019,8 @@ mod pallet { } }; if let Some(auto_resolve_block) = auto_resolve_block_opt { - MarketIdsPerDisputeBlock::::mutate( - auto_resolve_block, - |ids| -> (u32, u32) { - let ids_len = ids.len() as u32; - remove_item::, _>(ids, market_id); - (ids_len, disputes.len() as u32) - }, - ) + let ids_len = remove_auto_resolve::(market_id, auto_resolve_block); + (ids_len, disputes.len() as u32) } else { (0u32, disputes.len() as u32) } @@ -2894,6 +2888,14 @@ mod pallet { } } + fn remove_auto_resolve(market_id: &MarketIdOf, resolve_at: T::BlockNumber) -> u32 { + MarketIdsPerDisputeBlock::::mutate(resolve_at, |ids| -> u32 { + let ids_len = ids.len() as u32; + remove_item::, _>(ids, market_id); + ids_len + }) + } + impl DisputeResolutionApi for Pallet where T: Config, @@ -2912,10 +2914,10 @@ mod pallet { fn add_auto_resolve( market_id: &Self::MarketId, - resolution: Self::BlockNumber, + resolve_at: Self::BlockNumber, ) -> Result { let ids_len = >::try_mutate( - resolution, + resolve_at, |ids| -> Result { ids.try_push(*market_id).map_err(|_| >::StorageOverflow)?; Ok(ids.len() as u32) @@ -2924,11 +2926,8 @@ mod pallet { Ok(ids_len) } - fn remove_auto_resolve(market_id: &Self::MarketId, resolution: Self::BlockNumber) -> u32 { - MarketIdsPerDisputeBlock::::mutate(resolution, |ids| -> u32 { - remove_item::, _>(ids, market_id); - ids.len() as u32 - }) + fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32 { + remove_auto_resolve::(market_id, resolve_at) } } } From 65be71467fc7736b29f7babc8e9cf06bd474f1f9 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 10:44:19 +0100 Subject: [PATCH 60/93] fmt --- zrml/prediction-markets/src/lib.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 94f23f213..63d1e0c63 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -2888,7 +2888,10 @@ mod pallet { } } - fn remove_auto_resolve(market_id: &MarketIdOf, resolve_at: T::BlockNumber) -> u32 { + fn remove_auto_resolve( + market_id: &MarketIdOf, + resolve_at: T::BlockNumber, + ) -> u32 { MarketIdsPerDisputeBlock::::mutate(resolve_at, |ids| -> u32 { let ids_len = ids.len() as u32; remove_item::, _>(ids, market_id); From e5d59ed4846ca042c959cc5a40350e812937bf8e Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 10:48:30 +0100 Subject: [PATCH 61/93] remove TODO --- zrml/court/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/zrml/court/src/lib.rs b/zrml/court/src/lib.rs index bd2550e9e..05b93df9d 100644 --- a/zrml/court/src/lib.rs +++ b/zrml/court/src/lib.rs @@ -578,7 +578,6 @@ mod pallet { market.dispute_mechanism == MarketDisputeMechanism::Court, Error::::MarketDoesNotHaveCourtMechanism ); - // TODO when does court fail? Ok(false) } } From fb48a7ef794276819357a6f735b379c5e676e9fb Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 13:44:28 +0100 Subject: [PATCH 62/93] add expired report period check --- primitives/src/traits/dispute_api.rs | 8 +++++++- zrml/authorized/src/lib.rs | 22 +++++++++++++++++----- zrml/authorized/src/mock.rs | 12 ++++++++++-- zrml/court/src/mock.rs | 13 ++++++++++--- zrml/prediction-markets/src/lib.rs | 8 ++++++++ zrml/simple-disputes/src/mock.rs | 12 ++++++++++-- 6 files changed, 62 insertions(+), 13 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 560346b7a..24941bd67 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -16,7 +16,7 @@ // along with Zeitgeist. If not, see . use crate::{market::MarketDispute, outcome_report::OutcomeReport, types::Market}; -use frame_support::{dispatch::DispatchResult, pallet_prelude::Weight}; +use frame_support::{dispatch::DispatchResult, pallet_prelude::Weight, BoundedVec}; use sp_runtime::DispatchError; pub trait DisputeApi { @@ -78,6 +78,7 @@ pub trait DisputeResolutionApi { type AccountId; type BlockNumber; type MarketId; + type MaxDisputes; type Moment; /// Resolve a market. @@ -109,4 +110,9 @@ pub trait DisputeResolutionApi { /// /// Returns the number of elements in the storage structure. fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32; + + /// Get the disputes of a market. + fn get_disputes( + market_id: &Self::MarketId, + ) -> BoundedVec, Self::MaxDisputes>; } diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index f4743516c..45f54474d 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -86,6 +86,9 @@ mod pallet { market.dispute_mechanism == MarketDisputeMechanism::Authorized, Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); + let disputes = T::DisputeResolution::get_disputes(&market_id); + let not_expired = !Self::is_expired(disputes.as_slice(), &market_id)?; + ensure!(not_expired, Error::::ReportPeriodExpired); let ids_len_1 = Self::remove_auto_resolve(&market_id); let now = frame_system::Pallet::::block_number(); @@ -144,6 +147,8 @@ mod pallet { MarketDoesNotHaveDisputeMechanismAuthorized, /// An account attempts to submit a report to an undisputed market. MarketIsNotDisputed, + /// The report period is expired. + ReportPeriodExpired, /// Only one dispute is allowed. OnlyOneDisputeAllowed, /// The report does not match the market's type. @@ -182,6 +187,17 @@ mod pallet { 0u32 } } + + fn is_expired( + disputes: &[MarketDispute], + market_id: &MarketIdOf, + ) -> Result { + let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; + let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); + let now = frame_system::Pallet::::block_number(); + let is_expired = last_dispute.at.saturating_add(T::ReportPeriod::get()) < now; + Ok(is_unreported && is_expired) + } } impl DisputeApi for Pallet @@ -245,11 +261,7 @@ mod pallet { market.dispute_mechanism == MarketDisputeMechanism::Authorized, Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; - let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); - let now = frame_system::Pallet::::block_number(); - let is_expired = last_dispute.at.saturating_add(T::ReportPeriod::get()) < now; - Ok(is_unreported && is_expired) + Self::is_expired(disputes, market_id) } } diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 59c4b1926..613792b11 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -22,6 +22,7 @@ use frame_support::{ construct_runtime, ord_parameter_types, pallet_prelude::{DispatchError, Weight}, traits::Everything, + BoundedVec, }; use frame_system::EnsureSignedBy; use sp_runtime::{ @@ -35,8 +36,8 @@ use zeitgeist_primitives::{ }, traits::DisputeResolutionApi, types::{ - AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketId, Moment, - UncheckedExtrinsicTest, + AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketDispute, + MarketId, Moment, UncheckedExtrinsicTest, }, }; @@ -70,6 +71,7 @@ impl DisputeResolutionApi for NoopResolution { type AccountId = AccountIdTest; type BlockNumber = BlockNumber; type MarketId = MarketId; + type MaxDisputes = u32; type Moment = Moment; fn resolve( @@ -89,6 +91,12 @@ impl DisputeResolutionApi for NoopResolution { fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { 0u32 } + + fn get_disputes( + _market_id: &Self::MarketId, + ) -> BoundedVec, Self::MaxDisputes> { + Default::default() + } } impl crate::Config for Runtime { diff --git a/zrml/court/src/mock.rs b/zrml/court/src/mock.rs index 27b47da00..7ca34ff28 100644 --- a/zrml/court/src/mock.rs +++ b/zrml/court/src/mock.rs @@ -23,7 +23,7 @@ use frame_support::{ pallet_prelude::{DispatchError, Weight}, parameter_types, traits::Everything, - PalletId, + BoundedVec, PalletId, }; use sp_runtime::{ testing::Header, @@ -36,8 +36,8 @@ use zeitgeist_primitives::{ }, traits::DisputeResolutionApi, types::{ - AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketId, Moment, - UncheckedExtrinsicTest, + AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketDispute, + MarketId, Moment, UncheckedExtrinsicTest, }, }; @@ -73,6 +73,7 @@ impl DisputeResolutionApi for NoopResolution { type AccountId = AccountIdTest; type BlockNumber = BlockNumber; type MarketId = MarketId; + type MaxDisputes = u32; type Moment = Moment; fn resolve( @@ -92,6 +93,12 @@ impl DisputeResolutionApi for NoopResolution { fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { 0u32 } + + fn get_disputes( + _market_id: &Self::MarketId, + ) -> BoundedVec, Self::MaxDisputes> { + Default::default() + } } impl crate::Config for Runtime { diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 63d1e0c63..54ed58e8e 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -2906,6 +2906,7 @@ mod pallet { type AccountId = T::AccountId; type BlockNumber = T::BlockNumber; type MarketId = MarketIdOf; + type MaxDisputes = T::MaxDisputes; type Moment = MomentOf; fn resolve( @@ -2932,5 +2933,12 @@ mod pallet { fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32 { remove_auto_resolve::(market_id, resolve_at) } + + fn get_disputes( + market_id: &Self::MarketId, + ) -> BoundedVec, Self::MaxDisputes> + { + Disputes::::get(market_id) + } } } diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index a3db7fac0..af2b0d8d4 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -22,6 +22,7 @@ use frame_support::{ construct_runtime, pallet_prelude::{DispatchError, Weight}, traits::Everything, + BoundedVec, }; use sp_runtime::{ testing::Header, @@ -33,8 +34,8 @@ use zeitgeist_primitives::{ }, traits::DisputeResolutionApi, types::{ - AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketId, Moment, - UncheckedExtrinsicTest, + AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketDispute, + MarketId, Moment, UncheckedExtrinsicTest, }, }; @@ -60,6 +61,7 @@ impl DisputeResolutionApi for NoopResolution { type AccountId = AccountIdTest; type BlockNumber = BlockNumber; type MarketId = MarketId; + type MaxDisputes = u32; type Moment = Moment; fn resolve( @@ -79,6 +81,12 @@ impl DisputeResolutionApi for NoopResolution { fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { 0u32 } + + fn get_disputes( + _market_id: &Self::MarketId, + ) -> BoundedVec, Self::MaxDisputes> { + Default::default() + } } impl crate::Config for Runtime { From 7657bf6a82ad20a958bc2719288d3a7e89dc509a Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 14:04:26 +0100 Subject: [PATCH 63/93] rename to has_failed --- primitives/src/traits/dispute_api.rs | 4 ++-- zrml/authorized/src/lib.rs | 2 +- zrml/court/src/lib.rs | 2 +- zrml/prediction-markets/src/benchmarks.rs | 8 ++++---- zrml/prediction-markets/src/lib.rs | 20 ++++++++++---------- zrml/prediction-markets/src/tests.rs | 8 ++++---- zrml/simple-disputes/src/lib.rs | 2 +- 7 files changed, 23 insertions(+), 23 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 24941bd67..5774b9609 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -65,9 +65,9 @@ pub trait DisputeApi { ) -> Result, DispatchError>; /// Returns `true` if the market dispute mechanism - /// was unable to come to a conclusion within a specified time. + /// was unable to come to a conclusion. /// **May** assume that `market.dispute_mechanism` refers to the calling dispute API. - fn is_expired( + fn has_failed( disputes: &[MarketDispute], market_id: &Self::MarketId, market: &Market, diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 45f54474d..dc100f670 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -252,7 +252,7 @@ mod pallet { Ok(Self::get_auto_resolve(market_id)) } - fn is_expired( + fn has_failed( disputes: &[MarketDispute], market_id: &Self::MarketId, market: &Market>, diff --git a/zrml/court/src/lib.rs b/zrml/court/src/lib.rs index 05b93df9d..43aa369af 100644 --- a/zrml/court/src/lib.rs +++ b/zrml/court/src/lib.rs @@ -569,7 +569,7 @@ mod pallet { Ok(None) } - fn is_expired( + fn has_failed( _: &[MarketDispute], _: &Self::MarketId, market: &Market>, diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index bb652c243..32c0d3199 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -874,11 +874,11 @@ benchmarks! { now + authority_report_period.saturated_into() + 1u64.saturated_into() ); - let call = Call::::resolve_expired_mdm { market_id }; + let call = Call::::resolve_failed_mdm { market_id }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } verify { - assert_last_event::(Event::DisputeMechanismExpired::(market_id).into()); + assert_last_event::(Event::FailedDisputeMechanismResolved::(market_id).into()); } resolve_expired_mdm_authorized_categorical { @@ -912,11 +912,11 @@ benchmarks! { now + authority_report_period.saturated_into() + 1u64.saturated_into() ); - let call = Call::::resolve_expired_mdm { market_id }; + let call = Call::::resolve_failed_mdm { market_id }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } verify { - assert_last_event::(Event::DisputeMechanismExpired::(market_id).into()); + assert_last_event::(Event::FailedDisputeMechanismResolved::(market_id).into()); } handle_expired_advised_market { diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 54ed58e8e..91e2435f0 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -497,7 +497,7 @@ mod pallet { .max(T::WeightInfo::resolve_expired_mdm_authorized_scalar()) )] #[transactional] - pub fn resolve_expired_mdm( + pub fn resolve_failed_mdm( origin: OriginFor, #[pallet::compact] market_id: MarketIdOf, ) -> DispatchResultWithPostInfo { @@ -506,22 +506,22 @@ mod pallet { ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); let disputes = Disputes::::get(market_id); // TODO(#782): use multiple benchmarks paths for different dispute mechanisms - let is_expired = match market.dispute_mechanism { + let has_failed = match market.dispute_mechanism { MarketDisputeMechanism::Authorized => { - T::Authorized::is_expired(&disputes, &market_id, &market)? + T::Authorized::has_failed(&disputes, &market_id, &market)? } MarketDisputeMechanism::Court => { - T::Court::is_expired(&disputes, &market_id, &market)? + T::Court::has_failed(&disputes, &market_id, &market)? } MarketDisputeMechanism::SimpleDisputes => { - T::SimpleDisputes::is_expired(&disputes, &market_id, &market)? + T::SimpleDisputes::has_failed(&disputes, &market_id, &market)? } }; - ensure!(is_expired, Error::::DisputeMechanismNotExpired); + ensure!(has_failed, Error::::DisputeMechanismHasNotFailed); Self::on_resolution(&market_id, &market)?; - Self::deposit_event(Event::DisputeMechanismExpired(market_id)); + Self::deposit_event(Event::FailedDisputeMechanismResolved(market_id)); let weight = match market.market_type { MarketType::Scalar(_) => T::WeightInfo::resolve_expired_mdm_authorized_scalar(), @@ -1532,7 +1532,7 @@ mod pallet { /// registered on-chain. CannotDisputeSameOutcome, /// The market dispute mechanism has not failed. - DisputeMechanismNotExpired, + DisputeMechanismHasNotFailed, /// Only creator is able to edit the market. EditorNotCreator, /// EditReason's length greater than MaxEditReasonLen. @@ -1633,8 +1633,8 @@ mod pallet { BadOnInitialize, /// A complete set of assets has been bought \[market_id, amount_per_asset, buyer\] BoughtCompleteSet(MarketIdOf, BalanceOf, ::AccountId), - /// A market dispute mechansim has expired \[market_id\] - DisputeMechanismExpired(MarketIdOf), + /// A failed market dispute mechansim finally resolved \[market_id\] + FailedDisputeMechanismResolved(MarketIdOf), /// A market has been approved \[market_id, new_market_status\] MarketApproved(MarketIdOf, MarketStatus), /// A market has been created \[market_id, market_account, market\] diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 7fb143790..06f1273cd 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2326,7 +2326,7 @@ fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { assert_eq!(disputes.len(), 1); run_blocks(::ReportPeriod::get() + 1); - assert_ok!(PredictionMarkets::resolve_expired_mdm(Origin::signed(FRED), 0)); + assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), 0)); let market_after = MarketCommons::market(&0).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); @@ -3179,13 +3179,13 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { run_blocks(::ReportPeriod::get()); assert_noop!( - PredictionMarkets::resolve_expired_mdm(Origin::signed(FRED), market_id), - Error::::DisputeMechanismNotExpired + PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id), + Error::::DisputeMechanismHasNotFailed ); run_blocks(1); // ReportPeriod is now over - assert_ok!(PredictionMarkets::resolve_expired_mdm(Origin::signed(FRED), market_id)); + assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id)); let market_after = MarketCommons::market(&market_id).unwrap(); assert_eq!(market_after.status, MarketStatus::Resolved); diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index 0a45c318e..2ff308804 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -181,7 +181,7 @@ mod pallet { Ok(Self::get_auto_resolve(disputes, market)) } - fn is_expired( + fn has_failed( _: &[MarketDispute], _: &Self::MarketId, market: &Market>, From 5f036d32e93340e92f7486d77861ad29067d5756 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 14 Dec 2022 14:31:33 +0100 Subject: [PATCH 64/93] satisfy clippy --- zrml/authorized/src/lib.rs | 20 ++++++++++---------- zrml/prediction-markets/src/benchmarks.rs | 8 ++++---- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index dc100f670..abcaee493 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -87,8 +87,10 @@ mod pallet { Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); let disputes = T::DisputeResolution::get_disputes(&market_id); - let not_expired = !Self::is_expired(disputes.as_slice(), &market_id)?; - ensure!(not_expired, Error::::ReportPeriodExpired); + if let Some(dispute) = disputes.last() { + let not_expired = !Self::is_expired(&market_id, dispute.at); + ensure!(not_expired, Error::::ReportPeriodExpired); + } let ids_len_1 = Self::remove_auto_resolve(&market_id); let now = frame_system::Pallet::::block_number(); @@ -188,15 +190,11 @@ mod pallet { } } - fn is_expired( - disputes: &[MarketDispute], - market_id: &MarketIdOf, - ) -> Result { - let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; + fn is_expired(market_id: &MarketIdOf, start: T::BlockNumber) -> bool { let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); let now = frame_system::Pallet::::block_number(); - let is_expired = last_dispute.at.saturating_add(T::ReportPeriod::get()) < now; - Ok(is_unreported && is_expired) + let is_expired = start.saturating_add(T::ReportPeriod::get()) < now; + is_unreported && is_expired } } @@ -261,7 +259,9 @@ mod pallet { market.dispute_mechanism == MarketDisputeMechanism::Authorized, Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - Self::is_expired(disputes, market_id) + + let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; + Ok(Self::is_expired(market_id, last_dispute.at)) } } diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 32c0d3199..ef442ff2d 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -456,7 +456,7 @@ benchmarks! { )?; >::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; Ok(()) })?; @@ -514,7 +514,7 @@ benchmarks! { )?; >::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; Ok(()) })?; @@ -958,7 +958,7 @@ benchmarks! { OutcomeReport::Categorical(1u16) )?; >::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; Ok(()) })?; @@ -1002,7 +1002,7 @@ benchmarks! { )?; >::mutate_market(&market_id, |market| { // to allow multiple disputes use simple disputes - market.dispute_mechanism = MarketDisputeMechanism::Authorized; + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; Ok(()) })?; let market = >::market(&market_id)?; From 5f3fb41ba11393a42279836500f3ad71fe38d1dc Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 16 Dec 2022 15:32:08 +0100 Subject: [PATCH 65/93] check dispute resolution blocks --- zrml/authorized/src/mock.rs | 13 +++++++++--- zrml/authorized/src/tests.rs | 41 +++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 4 deletions(-) diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 613792b11..1e8091cb9 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -17,7 +17,10 @@ #![cfg(test)] +extern crate alloc; + use crate::{self as zrml_authorized}; +use alloc::vec::Vec; use frame_support::{ construct_runtime, ord_parameter_types, pallet_prelude::{DispatchError, Weight}, @@ -64,6 +67,8 @@ ord_parameter_types! { pub const AuthorizedDisputeResolutionUser: AccountIdTest = ALICE; } +pub static mut RESOLUTIONS: Vec<(MarketId, BlockNumber)> = Vec::new(); + // NoopResolution implements DisputeResolutionApi with no-ops. pub struct NoopResolution; @@ -82,13 +87,15 @@ impl DisputeResolutionApi for NoopResolution { } fn add_auto_resolve( - _market_id: &Self::MarketId, - _resolve_at: Self::BlockNumber, + market_id: &Self::MarketId, + resolve_at: Self::BlockNumber, ) -> Result { + unsafe { RESOLUTIONS.push((*market_id, resolve_at)) }; Ok(0u32) } - fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { + fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32 { + unsafe { RESOLUTIONS.retain(|(id, block)| !(id == market_id && block == &resolve_at)) }; 0u32 } diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index d79bd9e67..3efaff1ca 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -19,7 +19,9 @@ use crate::{ market_mock, - mock::{Authorized, AuthorizedDisputeResolutionUser, ExtBuilder, Origin, Runtime, BOB}, + mock::{ + Authorized, AuthorizedDisputeResolutionUser, ExtBuilder, Origin, Runtime, BOB, RESOLUTIONS, + }, AuthorizedOutcomeReports, Error, }; use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; @@ -47,6 +49,43 @@ fn authorize_market_outcome_inserts_a_new_outcome() { }); } +#[test] +fn authorize_market_outcome_resets_dispute_resolution() { + ExtBuilder::default().build().execute_with(|| { + Markets::::insert(0, market_mock::()); + assert_ok!(Authorized::authorize_market_outcome( + Origin::signed(AuthorizedDisputeResolutionUser::get()), + 0, + OutcomeReport::Scalar(1) + )); + let now = frame_system::Pallet::::block_number(); + let resolve_at_0 = now + ::CorrectionPeriod::get(); + assert_eq!( + AuthorizedOutcomeReports::::get(0).unwrap(), + AuthorityReport { outcome: OutcomeReport::Scalar(1), resolve_at: resolve_at_0 } + ); + + unsafe { + assert_eq!(RESOLUTIONS, vec![(0, resolve_at_0)]); + } + + frame_system::Pallet::::set_block_number(resolve_at_0 - 1); + let now = frame_system::Pallet::::block_number(); + let resolve_at_1 = now + ::CorrectionPeriod::get(); + + assert_ok!(Authorized::authorize_market_outcome( + Origin::signed(AuthorizedDisputeResolutionUser::get()), + 0, + OutcomeReport::Scalar(2) + )); + + // expect one tuple inside vector (reset happened) + unsafe { + assert_eq!(RESOLUTIONS, vec![(0, resolve_at_1)]); + } + }); +} + #[test] fn authorize_market_outcome_fails_if_market_does_not_exist() { ExtBuilder::default().build().execute_with(|| { From de1c7d25eb23ba2f95fac2dda1e323ea213831ca Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 16 Dec 2022 17:21:26 +0100 Subject: [PATCH 66/93] use mock storage with unsafe --- zrml/authorized/src/mock.rs | 38 +++++++++--- zrml/authorized/src/tests.rs | 108 ++++++++++++++++++++++++++++++++++- 2 files changed, 137 insertions(+), 9 deletions(-) diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 1e8091cb9..d20c12150 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -20,10 +20,10 @@ extern crate alloc; use crate::{self as zrml_authorized}; -use alloc::vec::Vec; +use alloc::{vec, vec::Vec}; use frame_support::{ construct_runtime, ord_parameter_types, - pallet_prelude::{DispatchError, Weight}, + pallet_prelude::{DispatchError, Get, Weight}, traits::Everything, BoundedVec, }; @@ -40,7 +40,7 @@ use zeitgeist_primitives::{ traits::DisputeResolutionApi, types::{ AccountIdTest, Balance, BlockNumber, BlockTest, Hash, Index, Market, MarketDispute, - MarketId, Moment, UncheckedExtrinsicTest, + MarketId, Moment, OutcomeReport, UncheckedExtrinsicTest, }, }; @@ -69,14 +69,25 @@ ord_parameter_types! { pub static mut RESOLUTIONS: Vec<(MarketId, BlockNumber)> = Vec::new(); -// NoopResolution implements DisputeResolutionApi with no-ops. -pub struct NoopResolution; +pub static mut WITH_DISPUTE: bool = false; -impl DisputeResolutionApi for NoopResolution { +pub struct MaxDisputes; +impl Get for MaxDisputes { + fn get() -> u32 { + 64u32 + } +} + +type MaxDisputesTest = MaxDisputes; + +// MockResolution implements DisputeResolutionApi with no-ops. +pub struct MockResolution; + +impl DisputeResolutionApi for MockResolution { type AccountId = AccountIdTest; type BlockNumber = BlockNumber; type MarketId = MarketId; - type MaxDisputes = u32; + type MaxDisputes = MaxDisputesTest; type Moment = Moment; fn resolve( @@ -102,6 +113,17 @@ impl DisputeResolutionApi for NoopResolution { fn get_disputes( _market_id: &Self::MarketId, ) -> BoundedVec, Self::MaxDisputes> { + unsafe { + if WITH_DISPUTE { + return BoundedVec::try_from(vec![MarketDispute { + at: 42u64, + by: BOB, + outcome: OutcomeReport::Scalar(42), + }]) + .unwrap(); + } + } + Default::default() } } @@ -110,7 +132,7 @@ impl crate::Config for Runtime { type ReportPeriod = ReportPeriod; type Event = (); type CorrectionPeriod = CorrectionPeriod; - type DisputeResolution = NoopResolution; + type DisputeResolution = MockResolution; type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; type AuthorizedDisputeResolutionOrigin = diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index 3efaff1ca..7edcf7284 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -21,13 +21,14 @@ use crate::{ market_mock, mock::{ Authorized, AuthorizedDisputeResolutionUser, ExtBuilder, Origin, Runtime, BOB, RESOLUTIONS, + WITH_DISPUTE, }, AuthorizedOutcomeReports, Error, }; use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; use zeitgeist_primitives::{ traits::DisputeApi, - types::{AuthorityReport, MarketDisputeMechanism, MarketStatus, OutcomeReport}, + types::{AuthorityReport, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport}, }; use zrml_market_commons::Markets; @@ -83,6 +84,10 @@ fn authorize_market_outcome_resets_dispute_resolution() { unsafe { assert_eq!(RESOLUTIONS, vec![(0, resolve_at_1)]); } + + unsafe { + RESOLUTIONS.clear(); + } }); } @@ -233,3 +238,104 @@ fn authorized_market_outcome_can_handle_multiple_markets() { ); }); } + +#[test] +fn get_auto_resolve_works() { + ExtBuilder::default().build().execute_with(|| { + frame_system::Pallet::::set_block_number(42); + let market = market_mock::(); + Markets::::insert(0, &market); + assert_ok!(Authorized::authorize_market_outcome( + Origin::signed(AuthorizedDisputeResolutionUser::get()), + 0, + OutcomeReport::Scalar(1) + )); + let now = frame_system::Pallet::::block_number(); + let resolve_at = now + ::CorrectionPeriod::get(); + assert_eq!(Authorized::get_auto_resolve(&[], &0, &market).unwrap(), Some(resolve_at),); + }); +} + +#[test] +fn get_auto_resolve_returns_none_without_market_storage() { + ExtBuilder::default().build().execute_with(|| { + let market = market_mock::(); + assert_eq!(Authorized::get_auto_resolve(&[], &0, &market).unwrap(), None,); + }); +} + +#[test] +fn has_failed_works() { + ExtBuilder::default().build().execute_with(|| { + frame_system::Pallet::::set_block_number(42); + let market = market_mock::(); + Markets::::insert(0, &market); + let now = frame_system::Pallet::::block_number(); + let last_dispute = MarketDispute { at: now, by: BOB, outcome: OutcomeReport::Scalar(1) }; + + // not reported and not expired + assert!(!Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); + + // not reported and expired + frame_system::Pallet::::set_block_number( + now + ::ReportPeriod::get() + 1, + ); + assert!(Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); + + // report + assert_ok!(Authorized::authorize_market_outcome( + Origin::signed(AuthorizedDisputeResolutionUser::get()), + 0, + OutcomeReport::Scalar(1) + )); + + // reported and expired + assert!(!Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); + + frame_system::Pallet::::set_block_number( + now + ::ReportPeriod::get() - 1, + ); + + // reported and not expired + assert!(!Authorized::has_failed(&[last_dispute], &0, &market).unwrap()); + }); +} + +#[test] +fn authorize_market_outcome_fails_with_report_period_expired() { + ExtBuilder::default().build().execute_with(|| { + use zeitgeist_primitives::traits::DisputeResolutionApi; + + unsafe { + WITH_DISPUTE = true; + } + frame_system::Pallet::::set_block_number(42); + let market = market_mock::(); + Markets::::insert(0, &market); + + let dispute_at = 42; + let last_dispute = + MarketDispute { at: dispute_at, by: BOB, outcome: OutcomeReport::Scalar(42) }; + assert_eq!( + ::DisputeResolution::get_disputes(&0).pop().unwrap(), + last_dispute + ); + + frame_system::Pallet::::set_block_number( + dispute_at + ::ReportPeriod::get() + 1, + ); + + assert_noop!( + Authorized::authorize_market_outcome( + Origin::signed(AuthorizedDisputeResolutionUser::get()), + 0, + OutcomeReport::Scalar(1) + ), + Error::::ReportPeriodExpired + ); + + unsafe { + WITH_DISPUTE = false; + } + }); +} From f9eb2388be494c3897ff877e9dd7c06df54c6641 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 19 Dec 2022 10:20:09 +0100 Subject: [PATCH 67/93] use MarketIdsPerDisputeBlock inside mock --- zrml/authorized/src/lib.rs | 13 ++++++++ zrml/authorized/src/mock.rs | 38 +++++++++++------------ zrml/authorized/src/tests.rs | 59 +++++++++++++++++------------------- 3 files changed, 59 insertions(+), 51 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index abcaee493..567906cd9 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -41,6 +41,8 @@ mod pallet { traits::{Currency, Get, Hooks, IsType, StorageVersion}, PalletId, Twox64Concat, }; + #[cfg(test)] + use frame_support::{pallet_prelude::ValueQuery, BoundedVec}; use frame_system::pallet_prelude::OriginFor; use sp_runtime::{traits::Saturating, DispatchError}; use zeitgeist_primitives::{ @@ -272,6 +274,17 @@ mod pallet { #[pallet::getter(fn outcomes)] pub type AuthorizedOutcomeReports = StorageMap<_, Twox64Concat, MarketIdOf, AuthorityReport, OptionQuery>; + + /// Only used for testing the dispute resolution API to prediction-markets + #[cfg(test)] + #[pallet::storage] + pub type MarketIdsPerDisputeBlock = StorageMap< + _, + Twox64Concat, + T::BlockNumber, + BoundedVec, CacheSize>, + ValueQuery, + >; } #[cfg(any(feature = "runtime-benchmarks", test))] diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index d20c12150..3ce134128 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -67,10 +67,6 @@ ord_parameter_types! { pub const AuthorizedDisputeResolutionUser: AccountIdTest = ALICE; } -pub static mut RESOLUTIONS: Vec<(MarketId, BlockNumber)> = Vec::new(); - -pub static mut WITH_DISPUTE: bool = false; - pub struct MaxDisputes; impl Get for MaxDisputes { fn get() -> u32 { @@ -101,30 +97,32 @@ impl DisputeResolutionApi for MockResolution { market_id: &Self::MarketId, resolve_at: Self::BlockNumber, ) -> Result { - unsafe { RESOLUTIONS.push((*market_id, resolve_at)) }; - Ok(0u32) + let ids_len = >::try_mutate( + resolve_at, + |ids| -> Result { + ids.try_push(*market_id).map_err(|_| DispatchError::Other("Storage Overflow"))?; + Ok(ids.len() as u32) + }, + )?; + Ok(ids_len) } fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32 { - unsafe { RESOLUTIONS.retain(|(id, block)| !(id == market_id && block == &resolve_at)) }; - 0u32 + >::mutate(resolve_at, |ids| -> u32 { + ids.retain(|id| id != market_id); + ids.len() as u32 + }) } fn get_disputes( _market_id: &Self::MarketId, ) -> BoundedVec, Self::MaxDisputes> { - unsafe { - if WITH_DISPUTE { - return BoundedVec::try_from(vec![MarketDispute { - at: 42u64, - by: BOB, - outcome: OutcomeReport::Scalar(42), - }]) - .unwrap(); - } - } - - Default::default() + BoundedVec::try_from(vec![MarketDispute { + at: 42u64, + by: BOB, + outcome: OutcomeReport::Scalar(42), + }]) + .unwrap() } } diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index 7edcf7284..182f9b7e6 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -19,15 +19,12 @@ use crate::{ market_mock, - mock::{ - Authorized, AuthorizedDisputeResolutionUser, ExtBuilder, Origin, Runtime, BOB, RESOLUTIONS, - WITH_DISPUTE, - }, - AuthorizedOutcomeReports, Error, + mock::{Authorized, AuthorizedDisputeResolutionUser, ExtBuilder, Origin, Runtime, BOB}, + AuthorizedOutcomeReports, Error, MarketIdsPerDisputeBlock, }; use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; use zeitgeist_primitives::{ - traits::DisputeApi, + traits::{DisputeApi, DisputeResolutionApi}, types::{AuthorityReport, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport}, }; use zrml_market_commons::Markets; @@ -54,10 +51,11 @@ fn authorize_market_outcome_inserts_a_new_outcome() { fn authorize_market_outcome_resets_dispute_resolution() { ExtBuilder::default().build().execute_with(|| { Markets::::insert(0, market_mock::()); + assert_ok!(Authorized::authorize_market_outcome( Origin::signed(AuthorizedDisputeResolutionUser::get()), 0, - OutcomeReport::Scalar(1) + OutcomeReport::Scalar(1), )); let now = frame_system::Pallet::::block_number(); let resolve_at_0 = now + ::CorrectionPeriod::get(); @@ -66,9 +64,7 @@ fn authorize_market_outcome_resets_dispute_resolution() { AuthorityReport { outcome: OutcomeReport::Scalar(1), resolve_at: resolve_at_0 } ); - unsafe { - assert_eq!(RESOLUTIONS, vec![(0, resolve_at_0)]); - } + assert_eq!(MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![0]); frame_system::Pallet::::set_block_number(resolve_at_0 - 1); let now = frame_system::Pallet::::block_number(); @@ -80,14 +76,8 @@ fn authorize_market_outcome_resets_dispute_resolution() { OutcomeReport::Scalar(2) )); - // expect one tuple inside vector (reset happened) - unsafe { - assert_eq!(RESOLUTIONS, vec![(0, resolve_at_1)]); - } - - unsafe { - RESOLUTIONS.clear(); - } + assert_eq!(MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![]); + assert_eq!(MarketIdsPerDisputeBlock::::get(resolve_at_1), vec![0]); }); } @@ -265,7 +255,7 @@ fn get_auto_resolve_returns_none_without_market_storage() { } #[test] -fn has_failed_works() { +fn has_failed_works_without_report() { ExtBuilder::default().build().execute_with(|| { frame_system::Pallet::::set_block_number(42); let market = market_mock::(); @@ -280,20 +270,35 @@ fn has_failed_works() { frame_system::Pallet::::set_block_number( now + ::ReportPeriod::get() + 1, ); - assert!(Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); - // report + assert!(Authorized::has_failed(&[last_dispute], &0, &market).unwrap()); + }); +} + +#[test] +fn has_failed_works_with_report() { + ExtBuilder::default().build().execute_with(|| { + frame_system::Pallet::::set_block_number(42); + let market = market_mock::(); + Markets::::insert(0, &market); + let now = frame_system::Pallet::::block_number(); + let last_dispute = MarketDispute { at: now, by: BOB, outcome: OutcomeReport::Scalar(1) }; + assert_ok!(Authorized::authorize_market_outcome( Origin::signed(AuthorizedDisputeResolutionUser::get()), 0, OutcomeReport::Scalar(1) )); + frame_system::Pallet::::set_block_number( + now + ::ReportPeriod::get() - 1, + ); + // reported and expired assert!(!Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); frame_system::Pallet::::set_block_number( - now + ::ReportPeriod::get() - 1, + now + ::ReportPeriod::get() + 1, ); // reported and not expired @@ -304,11 +309,6 @@ fn has_failed_works() { #[test] fn authorize_market_outcome_fails_with_report_period_expired() { ExtBuilder::default().build().execute_with(|| { - use zeitgeist_primitives::traits::DisputeResolutionApi; - - unsafe { - WITH_DISPUTE = true; - } frame_system::Pallet::::set_block_number(42); let market = market_mock::(); Markets::::insert(0, &market); @@ -316,6 +316,7 @@ fn authorize_market_outcome_fails_with_report_period_expired() { let dispute_at = 42; let last_dispute = MarketDispute { at: dispute_at, by: BOB, outcome: OutcomeReport::Scalar(42) }; + // get_disputes returns a sample dispute in the mock assert_eq!( ::DisputeResolution::get_disputes(&0).pop().unwrap(), last_dispute @@ -333,9 +334,5 @@ fn authorize_market_outcome_fails_with_report_period_expired() { ), Error::::ReportPeriodExpired ); - - unsafe { - WITH_DISPUTE = false; - } }); } From 0f3b1e12d4d4a973016ddee576a2a086192b6dcd Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 19 Dec 2022 14:12:56 +0100 Subject: [PATCH 68/93] prepare authority account id --- zrml/authorized/src/lib.rs | 40 +++++++++++----- zrml/authorized/src/tests.rs | 10 ++-- zrml/prediction-markets/src/tests.rs | 72 ++++------------------------ 3 files changed, 43 insertions(+), 79 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 567906cd9..c39580c85 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -88,10 +88,19 @@ mod pallet { market.dispute_mechanism == MarketDisputeMechanism::Authorized, Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - let disputes = T::DisputeResolution::get_disputes(&market_id); - if let Some(dispute) = disputes.last() { - let not_expired = !Self::is_expired(&market_id, dispute.at); - ensure!(not_expired, Error::::ReportPeriodExpired); + + // TODO (#918): when we later allow a simple account id to be the authority, this expiration limit becomes useful + #[cfg(not(test))] + let fallible_authority = false; + #[cfg(test)] + let fallible_authority = true; + + if fallible_authority { + let disputes = T::DisputeResolution::get_disputes(&market_id); + if let Some(dispute) = disputes.last() { + let not_expired = !Self::has_expired(dispute.at); + ensure!(not_expired, Error::::ReportPeriodExpired); + } } let ids_len_1 = Self::remove_auto_resolve(&market_id); @@ -109,6 +118,7 @@ mod pallet { #[pallet::config] pub trait Config: frame_system::Config { + /// In case the authority is a simple account: /// The period in which the authority has to report. This value must not be zero. /// This value should be fairly large, so that the authority has enough time to report. #[pallet::constant] @@ -192,11 +202,9 @@ mod pallet { } } - fn is_expired(market_id: &MarketIdOf, start: T::BlockNumber) -> bool { - let is_unreported = !AuthorizedOutcomeReports::::contains_key(market_id); + fn has_expired(start: T::BlockNumber) -> bool { let now = frame_system::Pallet::::block_number(); - let is_expired = start.saturating_add(T::ReportPeriod::get()) < now; - is_unreported && is_expired + start.saturating_add(T::ReportPeriod::get()) < now } } @@ -254,7 +262,7 @@ mod pallet { fn has_failed( disputes: &[MarketDispute], - market_id: &Self::MarketId, + _: &Self::MarketId, market: &Market>, ) -> Result { ensure!( @@ -262,8 +270,18 @@ mod pallet { Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; - Ok(Self::is_expired(market_id, last_dispute.at)) + // TODO (#918): when we later allow a simple account id to be the authority, this expiration limit becomes useful + #[cfg(not(test))] + let fallible_authority = false; + #[cfg(test)] + let fallible_authority = true; + if fallible_authority { + let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; + let has_expired = Self::has_expired(last_dispute.at); + return Ok(has_expired); + } + + Ok(false) } } diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index 182f9b7e6..18661af1c 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -263,10 +263,8 @@ fn has_failed_works_without_report() { let now = frame_system::Pallet::::block_number(); let last_dispute = MarketDispute { at: now, by: BOB, outcome: OutcomeReport::Scalar(1) }; - // not reported and not expired assert!(!Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); - // not reported and expired frame_system::Pallet::::set_block_number( now + ::ReportPeriod::get() + 1, ); @@ -276,7 +274,7 @@ fn has_failed_works_without_report() { } #[test] -fn has_failed_works_with_report() { +fn has_failed_works_with_renewed_reports() { ExtBuilder::default().build().execute_with(|| { frame_system::Pallet::::set_block_number(42); let market = market_mock::(); @@ -284,6 +282,8 @@ fn has_failed_works_with_report() { let now = frame_system::Pallet::::block_number(); let last_dispute = MarketDispute { at: now, by: BOB, outcome: OutcomeReport::Scalar(1) }; + // assume `authorize_market_outcome` is renewed indefintiely + // by a fallible authority (one account id) assert_ok!(Authorized::authorize_market_outcome( Origin::signed(AuthorizedDisputeResolutionUser::get()), 0, @@ -294,15 +294,13 @@ fn has_failed_works_with_report() { now + ::ReportPeriod::get() - 1, ); - // reported and expired assert!(!Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); frame_system::Pallet::::set_block_number( now + ::ReportPeriod::get() + 1, ); - // reported and not expired - assert!(!Authorized::has_failed(&[last_dispute], &0, &market).unwrap()); + assert!(Authorized::has_failed(&[last_dispute], &0, &market).unwrap()); }); } diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 06f1273cd..164f504e5 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2288,67 +2288,6 @@ fn dispute_fails_unless_reported_or_disputed_market(status: MarketStatus) { }); } -#[test] -fn it_resolves_a_disputed_market_to_default_if_dispute_mechanism_failed() { - ExtBuilder::default().build().execute_with(|| { - let end = 2; - assert_ok!(PredictionMarkets::create_market( - Origin::signed(ALICE), - BOB, - MarketPeriod::Block(0..2), - get_deadlines(), - gen_metadata(2), - MarketCreation::Permissionless, - MarketType::Categorical(::MinCategories::get()), - MarketDisputeMechanism::Authorized, - ScoringRule::CPMM, - )); - assert_ok!(PredictionMarkets::buy_complete_set(Origin::signed(CHARLIE), 0, CENT)); - - let market = MarketCommons::market(&0).unwrap(); - let grace_period = market.deadlines.grace_period; - run_to_block(end + grace_period + 1); - assert_ok!(PredictionMarkets::report( - Origin::signed(BOB), - 0, - OutcomeReport::Categorical(0) - )); - let dispute_at = end + grace_period + 2; - run_to_block(dispute_at); - assert_ok!(PredictionMarkets::dispute( - Origin::signed(CHARLIE), - 0, - OutcomeReport::Categorical(1) - )); - - let charlie_reserved = Balances::reserved_balance(&CHARLIE); - let disputes = crate::Disputes::::get(0); - assert_eq!(disputes.len(), 1); - - run_blocks(::ReportPeriod::get() + 1); - assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), 0)); - - let market_after = MarketCommons::market(&0).unwrap(); - assert_eq!(market_after.status, MarketStatus::Resolved); - let disputes = crate::Disputes::::get(0); - assert_eq!(disputes.len(), 0); - assert_ok!(PredictionMarkets::redeem_shares(Origin::signed(CHARLIE), 0)); - - // make sure rewards are right - // - // slashed amounts - // --------------------------- - // - Charlie's reserve: DisputeBond::get() - // The market defaults on the report provided by the oracle. - // Charlie disputed a different outcome than the oracle reported. - assert_eq!(Balances::free_balance(&CHARLIE), 1_000 * BASE - charlie_reserved); - - // The oracle report was accepted, so Alice is not slashed. - assert_eq!(Balances::free_balance(&ALICE), 1_000 * BASE); - assert_eq!(Balances::free_balance(&BOB), 1_000 * BASE); - }); -} - #[test] fn start_global_dispute_works() { ExtBuilder::default().build().execute_with(|| { @@ -3139,8 +3078,11 @@ fn authorized_correctly_resolves_disputed_market() { }); } +/* +TODO (#918): when we later allow a simple account id to be the authority, this expiration limit for the authority becomes useful + #[test] -fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { +fn on_resolution_defaults_to_oracle_report_in_case_of_failed_authorized_mdm() { ExtBuilder::default().build().execute_with(|| { assert!(Balances::free_balance(Treasury::account_id()).is_zero()); let end = 2; @@ -3166,6 +3108,8 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { market_id, OutcomeReport::Categorical(1) )); + let dispute_at = end + grace_period + 2; + run_to_block(dispute_at); assert_ok!(PredictionMarkets::dispute( Origin::signed(CHARLIE), market_id, @@ -3174,6 +3118,9 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { let market = MarketCommons::market(&market_id).unwrap(); assert_eq!(market.status, MarketStatus::Disputed); + let disputes = crate::Disputes::::get(0); + assert_eq!(disputes.len(), 1); + let charlie_reserved = Balances::reserved_balance(&CHARLIE); assert_eq!(charlie_reserved, DisputeBond::get()); @@ -3207,6 +3154,7 @@ fn on_resolution_defaults_to_oracle_report_in_case_of_unresolved_dispute() { assert_eq!(Balances::free_balance(Treasury::account_id()), charlie_reserved); }); } +*/ #[test] fn approve_market_correctly_unreserves_advisory_bond() { From 9d7f8e2a5e3e2902494c3a71580a2cf55708438e Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 19 Dec 2022 15:21:32 +0100 Subject: [PATCH 69/93] correct benchmarks --- zrml/authorized/src/lib.rs | 3 +-- zrml/prediction-markets/src/lib.rs | 11 +++++++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index c39580c85..117333ed9 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -277,8 +277,7 @@ mod pallet { let fallible_authority = true; if fallible_authority { let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; - let has_expired = Self::has_expired(last_dispute.at); - return Ok(has_expired); + return Ok(Self::has_expired(last_dispute.at)); } Ok(false) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 91e2435f0..108322d00 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -504,9 +504,11 @@ mod pallet { ensure_signed(origin)?; let market = >::market(&market_id)?; ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); + let disputes = Disputes::::get(market_id); + // TODO(#782): use multiple benchmarks paths for different dispute mechanisms - let has_failed = match market.dispute_mechanism { + let _has_failed = match market.dispute_mechanism { MarketDisputeMechanism::Authorized => { T::Authorized::has_failed(&disputes, &market_id, &market)? } @@ -517,7 +519,12 @@ mod pallet { T::SimpleDisputes::has_failed(&disputes, &market_id, &market)? } }; - ensure!(has_failed, Error::::DisputeMechanismHasNotFailed); + + // TODO (#918): benchmarks only reach the end when a dispute mechanism has failed + #[cfg(feature = "runtime-benchmarks")] + let _has_failed = true; + + ensure!(_has_failed, Error::::DisputeMechanismHasNotFailed); Self::on_resolution(&market_id, &market)?; From ccfa04fd516c485352151ad71675902702cd0ef0 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 21 Dec 2022 10:00:13 +0100 Subject: [PATCH 70/93] add mock storage --- zrml/authorized/src/lib.rs | 14 +------- zrml/authorized/src/mock.rs | 12 +++++-- zrml/authorized/src/mock_storage.rs | 52 +++++++++++++++++++++++++++++ zrml/authorized/src/tests.rs | 9 ++--- 4 files changed, 67 insertions(+), 20 deletions(-) create mode 100644 zrml/authorized/src/mock_storage.rs diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 117333ed9..152814741 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -24,6 +24,7 @@ mod authorized_pallet_api; mod benchmarks; pub mod migrations; mod mock; +mod mock_storage; mod tests; pub mod weights; @@ -41,8 +42,6 @@ mod pallet { traits::{Currency, Get, Hooks, IsType, StorageVersion}, PalletId, Twox64Concat, }; - #[cfg(test)] - use frame_support::{pallet_prelude::ValueQuery, BoundedVec}; use frame_system::pallet_prelude::OriginFor; use sp_runtime::{traits::Saturating, DispatchError}; use zeitgeist_primitives::{ @@ -291,17 +290,6 @@ mod pallet { #[pallet::getter(fn outcomes)] pub type AuthorizedOutcomeReports = StorageMap<_, Twox64Concat, MarketIdOf, AuthorityReport, OptionQuery>; - - /// Only used for testing the dispute resolution API to prediction-markets - #[cfg(test)] - #[pallet::storage] - pub type MarketIdsPerDisputeBlock = StorageMap< - _, - Twox64Concat, - T::BlockNumber, - BoundedVec, CacheSize>, - ValueQuery, - >; } #[cfg(any(feature = "runtime-benchmarks", test))] diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 3ce134128..eff0125e2 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -19,7 +19,7 @@ extern crate alloc; -use crate::{self as zrml_authorized}; +use crate::{self as zrml_authorized, mock_storage::pallet as mock_storage}; use alloc::{vec, vec::Vec}; use frame_support::{ construct_runtime, ord_parameter_types, @@ -60,6 +60,8 @@ construct_runtime!( MarketCommons: zrml_market_commons::{Pallet, Storage}, System: frame_system::{Call, Config, Event, Pallet, Storage}, Timestamp: pallet_timestamp::{Pallet}, + // Just a mock storage for testing. + MockStorage: mock_storage::{Storage}, } ); @@ -97,7 +99,7 @@ impl DisputeResolutionApi for MockResolution { market_id: &Self::MarketId, resolve_at: Self::BlockNumber, ) -> Result { - let ids_len = >::try_mutate( + let ids_len = >::try_mutate( resolve_at, |ids| -> Result { ids.try_push(*market_id).map_err(|_| DispatchError::Other("Storage Overflow"))?; @@ -108,7 +110,7 @@ impl DisputeResolutionApi for MockResolution { } fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32 { - >::mutate(resolve_at, |ids| -> u32 { + >::mutate(resolve_at, |ids| -> u32 { ids.retain(|id| id != market_id); ids.len() as u32 }) @@ -138,6 +140,10 @@ impl crate::Config for Runtime { type WeightInfo = crate::weights::WeightInfo; } +impl mock_storage::Config for Runtime { + type MarketCommons = MarketCommons; +} + impl frame_system::Config for Runtime { type AccountData = pallet_balances::AccountData; type AccountId = AccountIdTest; diff --git a/zrml/authorized/src/mock_storage.rs b/zrml/authorized/src/mock_storage.rs new file mode 100644 index 000000000..96dc6fd56 --- /dev/null +++ b/zrml/authorized/src/mock_storage.rs @@ -0,0 +1,52 @@ +// Copyright 2021-2022 Zeitgeist PM LLC. +// +// This file is part of Zeitgeist. +// +// Zeitgeist is free software: you can redistribute it and/or modify it +// under the terms of the GNU General Public License as published by the +// Free Software Foundation, either version 3 of the License, or (at +// your option) any later version. +// +// Zeitgeist is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Zeitgeist. If not, see . + +#![cfg(test)] +#![allow(dead_code)] + +#[frame_support::pallet] +pub(crate) mod pallet { + use core::marker::PhantomData; + use frame_support::pallet_prelude::*; + use zrml_market_commons::MarketCommonsPalletApi; + + pub(crate) type MarketIdOf = + <::MarketCommons as MarketCommonsPalletApi>::MarketId; + + pub type CacheSize = ConstU32<64>; + + #[pallet::config] + pub trait Config: frame_system::Config { + type MarketCommons: MarketCommonsPalletApi< + AccountId = Self::AccountId, + BlockNumber = Self::BlockNumber, + >; + } + + #[pallet::pallet] + pub struct Pallet(PhantomData); + + /// Only used for testing the dispute resolution API to prediction-markets + #[pallet::storage] + pub(crate) type MarketIdsPerDisputeBlock = StorageMap< + _, + Twox64Concat, + T::BlockNumber, + BoundedVec, CacheSize>, + ValueQuery, + >; +} diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index 18661af1c..2b3d65c66 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -20,7 +20,8 @@ use crate::{ market_mock, mock::{Authorized, AuthorizedDisputeResolutionUser, ExtBuilder, Origin, Runtime, BOB}, - AuthorizedOutcomeReports, Error, MarketIdsPerDisputeBlock, + mock_storage::pallet as mock_storage, + AuthorizedOutcomeReports, Error, }; use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; use zeitgeist_primitives::{ @@ -64,7 +65,7 @@ fn authorize_market_outcome_resets_dispute_resolution() { AuthorityReport { outcome: OutcomeReport::Scalar(1), resolve_at: resolve_at_0 } ); - assert_eq!(MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![0]); + assert_eq!(mock_storage::MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![0]); frame_system::Pallet::::set_block_number(resolve_at_0 - 1); let now = frame_system::Pallet::::block_number(); @@ -76,8 +77,8 @@ fn authorize_market_outcome_resets_dispute_resolution() { OutcomeReport::Scalar(2) )); - assert_eq!(MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![]); - assert_eq!(MarketIdsPerDisputeBlock::::get(resolve_at_1), vec![0]); + assert_eq!(mock_storage::MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![]); + assert_eq!(mock_storage::MarketIdsPerDisputeBlock::::get(resolve_at_1), vec![0]); }); } From cb038d8a97aaa2e9cc58e6747cfc16a3e2590b75 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 21 Dec 2022 12:42:11 +0100 Subject: [PATCH 71/93] correct start_global_disputes benchmark --- zrml/prediction-markets/src/benchmarks.rs | 33 +++++++++++++++++++---- zrml/prediction-markets/src/lib.rs | 14 ++++------ zrml/prediction-markets/src/weights.rs | 19 +++++++++---- 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index ef442ff2d..968c1228a 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -770,6 +770,7 @@ benchmarks! { start_global_dispute { let m in 1..CacheSize::get(); + let n in 1..CacheSize::get(); // no benchmarking component for max disputes here, // because MaxDisputes is enforced for the extrinsic @@ -779,11 +780,16 @@ benchmarks! { OutcomeReport::Scalar(u128::MAX), )?; + >::mutate_market(&market_id, |market| { + market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; + Ok(()) + })?; + // first element is the market id from above - let mut market_ids = BoundedVec::try_from(vec![market_id]).unwrap(); + let mut market_ids_1: BoundedVec, CacheSize> = Default::default(); assert_eq!(market_id, 0u128.saturated_into()); for i in 1..m { - market_ids.try_push(i.saturated_into()).unwrap(); + market_ids_1.try_push(i.saturated_into()).unwrap(); } let max_dispute_len = T::MaxDisputes::get(); @@ -800,11 +806,28 @@ benchmarks! { .dispatch_bypass_filter(RawOrigin::Signed(disputor.clone()).into())?; } + let market = >::market(&market_id.saturated_into()).unwrap(); + let disputes = Disputes::::get(market_id); + let last_dispute = disputes.last().unwrap(); + let dispute_duration_ends_at_block = last_dispute.at + market.deadlines.dispute_duration; + let mut market_ids_2: BoundedVec, CacheSize> = BoundedVec::try_from( + vec![market_id], + ).unwrap(); + for i in 1..n { + market_ids_2.try_push(i.saturated_into()).unwrap(); + } + MarketIdsPerDisputeBlock::::insert(dispute_duration_ends_at_block, market_ids_2); + let current_block: T::BlockNumber = (max_dispute_len + 1).saturated_into(); >::set_block_number(current_block); - // the complexity depends on MarketIdsPerDisputeBlock at the current block - // this is because a variable number of market ids need to be decoded from the storage - MarketIdsPerDisputeBlock::::insert(current_block, market_ids); + + #[cfg(feature = "with-global-disputes")] + { + let global_dispute_end = current_block + T::GlobalDisputePeriod::get(); + // the complexity depends on MarketIdsPerDisputeBlock at the current block + // this is because a variable number of market ids need to be decoded from the storage + MarketIdsPerDisputeBlock::::insert(global_dispute_end, market_ids_1); + } let call = Call::::start_global_dispute { market_id }; }: { diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 108322d00..c47064d18 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -1274,7 +1274,7 @@ mod pallet { /// The outcomes of the disputes and the report outcome /// are added to the global dispute voting outcomes. /// The bond of each dispute is the initial vote amount. - #[pallet::weight(T::WeightInfo::start_global_dispute(CacheSize::get()))] + #[pallet::weight(T::WeightInfo::start_global_dispute(CacheSize::get(), CacheSize::get()))] #[transactional] pub fn start_global_dispute( origin: OriginFor, @@ -1328,13 +1328,9 @@ mod pallet { // TODO(#372): Allow court with global disputes. // ensure, that global disputes controls the resolution now // it does not end after the dispute period now, but after the global dispute end - if let Some(auto_resolve_block) = - T::SimpleDisputes::get_auto_resolve(&disputes, &market_id, &market)? - { - MarketIdsPerDisputeBlock::::mutate(auto_resolve_block, |ids| { - remove_item::, _>(ids, &market_id); - }); - } + + // ignore first of tuple because we always have max disputes + let (_, ids_len_2) = Self::clear_auto_resolve(&market_id)?; let now = >::block_number(); let global_dispute_end = now.saturating_add(T::GlobalDisputePeriod::get()); @@ -1348,7 +1344,7 @@ mod pallet { Self::deposit_event(Event::GlobalDisputeStarted(market_id)); - Ok(Some(T::WeightInfo::start_global_dispute(market_ids_len)).into()) + Ok(Some(T::WeightInfo::start_global_dispute(market_ids_len, ids_len_2)).into()) } #[cfg(not(feature = "with-global-disputes"))] diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index 683f47367..78ef6a90f 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -59,7 +59,7 @@ pub trait WeightInfoZeitgeist { fn edit_market(m: u32) -> Weight; fn deploy_swap_pool_for_market_future_pool(a: u32, o: u32) -> Weight; fn deploy_swap_pool_for_market_open_pool(a: u32) -> Weight; - fn start_global_dispute(m: u32) -> Weight; + fn start_global_dispute(m: u32, n: u32) -> Weight; fn dispute_authorized() -> Weight; fn resolve_expired_mdm_authorized_scalar() -> Weight; fn resolve_expired_mdm_authorized_categorical() -> Weight; @@ -287,10 +287,19 @@ impl WeightInfoZeitgeist for WeightInfo { .saturating_add(T::DbWeight::get().writes(6 as Weight)) .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(a as Weight))) } - fn start_global_dispute(m: u32) -> Weight { - (6_559_000 as Weight) - // Standard Error: 1_000 - .saturating_add((2_000 as Weight).saturating_mul(m as Weight)) + // Storage: MarketCommons Markets (r:1 w:0) + // Storage: PredictionMarkets Disputes (r:1 w:0) + // Storage: GlobalDisputes Winners (r:1 w:1) + // Storage: GlobalDisputes Outcomes (r:7 w:7) + // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:2 w:2) + fn start_global_dispute(m: u32, n: u32) -> Weight { + (93_550_000 as Weight) + // Standard Error: 0 + .saturating_add((27_000 as Weight).saturating_mul(m as Weight)) + // Standard Error: 0 + .saturating_add((16_000 as Weight).saturating_mul(n as Weight)) + .saturating_add(T::DbWeight::get().reads(12 as Weight)) + .saturating_add(T::DbWeight::get().writes(10 as Weight)) } // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: MarketCommons Markets (r:1 w:1) From 8b81a11ac88978d19f2276942a21ae23e8ad0c8c Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 21 Dec 2022 16:32:09 +0100 Subject: [PATCH 72/93] improve migration --- runtime/common/src/lib.rs | 6 +- zrml/authorized/src/migrations.rs | 201 ------------ zrml/prediction-markets/src/migrations.rs | 380 ++++++++++------------ 3 files changed, 179 insertions(+), 408 deletions(-) diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index 5bbb934cf..b0a64b076 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -59,8 +59,7 @@ macro_rules! decl_common_types { Runtime, AllPalletsWithSystem, ( - zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, - zrml_authorized::migrations::AddFieldToAuthorityReport, + zrml_prediction_markets::migrations::AddFieldToAuthorityReport, ), >; @@ -72,8 +71,7 @@ macro_rules! decl_common_types { Runtime, AllPalletsWithSystem, ( - zrml_prediction_markets::migrations::UpdateMarketIdsPerDisputeBlock, - zrml_authorized::migrations::AddFieldToAuthorityReport, + zrml_prediction_markets::migrations::AddFieldToAuthorityReport, ), >; diff --git a/zrml/authorized/src/migrations.rs b/zrml/authorized/src/migrations.rs index 8892abb4b..55d6e03fb 100644 --- a/zrml/authorized/src/migrations.rs +++ b/zrml/authorized/src/migrations.rs @@ -15,207 +15,6 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{Config, Pallet}; -#[cfg(feature = "try-runtime")] -use alloc::string::ToString; -use alloc::vec::Vec; -use frame_support::{ - dispatch::Weight, - log, - migration::{put_storage_value, storage_iter}, - pallet_prelude::PhantomData, - traits::{Get, OnRuntimeUpgrade, StorageVersion}, -}; -#[cfg(feature = "try-runtime")] -use scale_info::prelude::format; -use sp_runtime::traits::Saturating; -use zeitgeist_primitives::types::{AuthorityReport, OutcomeReport}; - -const AUTHORIZED: &[u8] = b"Authorized"; -const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; - -const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; -const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; - -pub struct AddFieldToAuthorityReport(PhantomData); - -// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. -impl OnRuntimeUpgrade for AddFieldToAuthorityReport { - fn on_runtime_upgrade() -> Weight - where - T: Config, - { - let mut total_weight = T::DbWeight::get().reads(1); - let authorized_version = StorageVersion::get::>(); - if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION { - log::info!( - "AddFieldToAuthorityReport: authorized version is {:?}, require {:?};", - authorized_version, - AUTHORIZED_REQUIRED_STORAGE_VERSION, - ); - return total_weight; - } - log::info!("AddFieldToAuthorityReport: Starting..."); - - let mut new_storage_map = Vec::new(); - let now = >::block_number(); - for (key, old_value) in - storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) - { - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - - if let Some(outcome) = old_value { - let resolve_at: T::BlockNumber = - now.saturating_add(::ReportPeriod::get()); - let new_value = AuthorityReport { resolve_at, outcome }; - new_storage_map.push((key, new_value)); - } - } - - for (key, new_value) in new_storage_map { - put_storage_value::>>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - &key, - Some(new_value), - ); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - } - - StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::info!("AddFieldToAuthorityReport: Done!"); - total_weight - } - - #[cfg(feature = "try-runtime")] - fn pre_upgrade() -> Result<(), &'static str> { - use frame_support::traits::OnRuntimeUpgradeHelpersExt; - - let mut counter = 0_u32; - for (key, value) in - storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) - { - Self::set_temp_storage(value, &format!("{:?}", key.as_slice())); - - counter = counter.saturating_add(1_u32); - } - let counter_key = "counter_key".to_string(); - Self::set_temp_storage(counter, &counter_key); - Ok(()) - } - - #[cfg(feature = "try-runtime")] - fn post_upgrade() -> Result<(), &'static str> { - use frame_support::traits::OnRuntimeUpgradeHelpersExt; - let mut markets_count = 0_u32; - let old_counter_key = "counter_key".to_string(); - for (key, new_value) in storage_iter::>>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - ) { - let key_str = format!("{:?}", key.as_slice()); - if let Some(AuthorityReport { resolve_at: _, outcome }) = new_value { - let old_value: Option = Self::get_temp_storage(&key_str) - .unwrap_or_else(|| panic!("old value not found for market id {:?}", key_str)); - - assert_eq!(old_value.unwrap(), outcome); - - markets_count += 1_u32; - } else { - panic!( - "For market id {:?} storage iter should only find present (Option::Some) \ - values", - key_str - ); - } - } - let old_markets_count: u32 = - Self::get_temp_storage(&old_counter_key).expect("old counter key storage not found"); - assert_eq!(markets_count, old_markets_count); - Ok(()) - } -} - -#[cfg(test)] -mod tests_authorized { - use super::*; - use crate::mock::{ExtBuilder, Runtime}; - use frame_support::Twox64Concat; - use zeitgeist_primitives::types::{MarketId, OutcomeReport}; - - #[test] - fn on_runtime_upgrade_increments_the_storage_versions() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - AddFieldToAuthorityReport::::on_runtime_upgrade(); - let authorized_version = StorageVersion::get::>(); - assert_eq!(authorized_version, AUTHORIZED_NEXT_STORAGE_VERSION); - }); - } - - #[test] - fn on_runtime_sets_new_struct_with_resolve_at() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - - >::set_block_number(10_000); - - let hash = crate::migrations::utility::key_to_hash::(0); - let outcome = OutcomeReport::Categorical(42u16); - put_storage_value::>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - &hash, - Some(outcome.clone()), - ); - - AddFieldToAuthorityReport::::on_runtime_upgrade(); - - let now = >::block_number(); - let resolve_at: ::BlockNumber = - now.saturating_add(::ReportPeriod::get()); - let expected = Some(AuthorityReport { resolve_at, outcome }); - - let actual = frame_support::migration::get_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) - .unwrap(); - assert_eq!(expected, actual); - }); - } - - #[test] - fn on_runtime_is_noop_if_versions_are_not_correct() { - ExtBuilder::default().build().execute_with(|| { - // storage migration already executed (storage version is incremented already) - StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - - let hash = crate::migrations::utility::key_to_hash::(0); - let outcome = OutcomeReport::Categorical(42u16); - let now = >::block_number(); - let resolve_at: ::BlockNumber = - now.saturating_add(::ReportPeriod::get()); - let report = AuthorityReport { resolve_at, outcome }; - put_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, Some(report.clone())); - - AddFieldToAuthorityReport::::on_runtime_upgrade(); - - let actual = frame_support::migration::get_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) - .unwrap(); - assert_eq!(Some(report), actual); - }); - } - - fn set_up_chain() { - StorageVersion::new(AUTHORIZED_REQUIRED_STORAGE_VERSION).put::>(); - } -} - // We use these utilities to prevent having to make the swaps pallet a dependency of // prediciton-markets. The calls are based on the implementation of `StorageVersion`, found here: // https://github.com/paritytech/substrate/blob/bc7a1e6c19aec92bfa247d8ca68ec63e07061032/frame/support/src/traits/metadata.rs#L168-L230 diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 02a0b585b..f9312e6ee 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -15,302 +15,276 @@ // You should have received a copy of the GNU General Public License // along with Zeitgeist. If not, see . -use crate::{Config, Pallet}; -use alloc::vec::Vec; +// We use these utilities to prevent having to make the swaps pallet a dependency of +// prediciton-markets. The calls are based on the implementation of `StorageVersion`, found here: +// https://github.com/paritytech/substrate/blob/bc7a1e6c19aec92bfa247d8ca68ec63e07061032/frame/support/src/traits/metadata.rs#L168-L230 +// and previous migrations. + +use crate::Config; +#[cfg(feature = "try-runtime")] +use alloc::string::ToString; +use alloc::{collections::BTreeMap, vec::Vec}; +#[cfg(feature = "try-runtime")] +use frame_support::migration::storage_iter; use frame_support::{ dispatch::Weight, log, + migration::{put_storage_value, storage_key_iter}, pallet_prelude::PhantomData, traits::{Get, OnRuntimeUpgrade, StorageVersion}, + Twox64Concat, }; -use sp_runtime::traits::{One, Saturating}; -use zeitgeist_primitives::types::MarketDisputeMechanism; +use frame_system::pallet_prelude::BlockNumberFor; +#[cfg(feature = "try-runtime")] +use scale_info::prelude::format; +use zeitgeist_primitives::types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}; +use zrml_authorized::Pallet as AuthorizedPallet; use zrml_market_commons::MarketCommonsPalletApi; -const PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION: u16 = 6; -const PREDICTION_MARKETS_NEXT_STORAGE_VERSION: u16 = 7; +const AUTHORIZED: &[u8] = b"Authorized"; +const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; -pub struct UpdateMarketIdsPerDisputeBlock(PhantomData); +const AUTHORIZED_REQUIRED_STORAGE_VERSION: u16 = 2; +const AUTHORIZED_NEXT_STORAGE_VERSION: u16 = 3; -// Delete the auto resolution of authorized and court from `MarketIdsPerDisputeBlock` +pub struct AddFieldToAuthorityReport(PhantomData); + +// Add resolve_at block number value field to `AuthorizedOutcomeReports` map. impl OnRuntimeUpgrade - for UpdateMarketIdsPerDisputeBlock + for AddFieldToAuthorityReport { fn on_runtime_upgrade() -> Weight where T: Config, { let mut total_weight = T::DbWeight::get().reads(1); - let prediction_markets_version = StorageVersion::get::>(); - if prediction_markets_version != PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION { + let authorized_version = StorageVersion::get::>(); + if authorized_version != AUTHORIZED_REQUIRED_STORAGE_VERSION { log::info!( - "UpdateMarketIdsPerDisputeBlock: prediction-markets version is {:?}, require {:?}", - prediction_markets_version, - PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION, + "AddFieldToAuthorityReport: authorized version is {:?}, require {:?};", + authorized_version, + AUTHORIZED_REQUIRED_STORAGE_VERSION, ); return total_weight; } - log::info!("UpdateMarketIdsPerDisputeBlock: Starting..."); + log::info!("AddFieldToAuthorityReport: Starting..."); - let mut new_storage_map = Vec::new(); - let mut authorized_ids = Vec::new(); - for (key, mut bounded_vec) in crate::MarketIdsPerDisputeBlock::::iter() { + let mut authorized_resolutions = + BTreeMap::<::MarketId, BlockNumberFor>::new(); + for (resolve_at, bounded_vec) in crate::MarketIdsPerDisputeBlock::::iter() { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - bounded_vec.retain(|id| { + for id in bounded_vec.into_inner().iter() { if let Ok(market) = >::market(id) { - match market.dispute_mechanism { - MarketDisputeMechanism::Authorized => { - authorized_ids.push(*id); - false - } - MarketDisputeMechanism::Court => false, - MarketDisputeMechanism::SimpleDisputes => true, + if market.dispute_mechanism == MarketDisputeMechanism::Authorized { + authorized_resolutions.insert(*id, resolve_at); } } else { - log::warn!("UpdateMarketIdsPerDisputeBlock: Market id {:?} not found!", id); - // no market for id in MarketIdsPerDisputeBlock - false + log::warn!("AddFieldToAuthorityReport: Could not find market with id {:?}", id); } - }); - - new_storage_map.push((key, bounded_vec)); - } - - for (key, new_bounded_vec) in new_storage_map { - crate::MarketIdsPerDisputeBlock::::insert(key, new_bounded_vec); - total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + } } - let now = >::block_number(); - let mut resolve_at = - now.saturating_add(::ReportPeriod::get()); - for id in authorized_ids { - let mut ids = crate::MarketIdsPerDisputeBlock::::get(resolve_at); + let mut new_storage_map: Vec<( + ::MarketId, + AuthorityReport>, + )> = Vec::new(); + for (market_id, old_value) in storage_key_iter::< + ::MarketId, + Option, + Twox64Concat, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) + { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - while ids.is_full() { - resolve_at = resolve_at.saturating_add(One::one()); - ids = crate::MarketIdsPerDisputeBlock::::get(resolve_at); - total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + if let Some(outcome) = old_value { + let resolve_at: BlockNumberFor = *authorized_resolutions.get(&market_id).expect( + "For every market id in authorized_resolutions, there needs to be an \ + authorized outcome report!", + ); + + new_storage_map.push((market_id, AuthorityReport { resolve_at, outcome })); } - // is_full check above to ensure, that we can force_push - ids.force_push(id); - crate::MarketIdsPerDisputeBlock::::insert(resolve_at, ids); + } + for (market_id, new_value) in new_storage_map { + let hash = utility::key_to_hash::< + Twox64Concat, + ::MarketId, + >(market_id); + put_storage_value::>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &hash, + Some(new_value), + ); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } - StorageVersion::new(PREDICTION_MARKETS_NEXT_STORAGE_VERSION).put::>(); + StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); - log::info!("UpdateMarketIdsPerDisputeBlock: Done!"); + log::info!("AddFieldToAuthorityReport: Done!"); total_weight } #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { + use frame_support::traits::OnRuntimeUpgradeHelpersExt; + + let mut counter = 0_u32; + for (key, value) in + storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) + { + Self::set_temp_storage(value, &format!("{:?}", key.as_slice())); + + counter = counter.saturating_add(1_u32); + } + let counter_key = "counter_key".to_string(); + Self::set_temp_storage(counter, &counter_key); Ok(()) } #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { + use frame_support::traits::OnRuntimeUpgradeHelpersExt; + let mut markets_count = 0_u32; + let old_counter_key = "counter_key".to_string(); + for (key, new_value) in storage_iter::>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + ) { + let key_str = format!("{:?}", key.as_slice()); + if let Some(AuthorityReport { resolve_at: _, outcome }) = new_value { + let old_value: Option = Self::get_temp_storage(&key_str) + .unwrap_or_else(|| panic!("old value not found for market id {:?}", key_str)); + + assert_eq!(old_value.unwrap(), outcome); + + markets_count += 1_u32; + } else { + panic!( + "For market id {:?} storage iter should only find present (Option::Some) \ + values", + key_str + ); + } + } + let old_markets_count: u32 = + Self::get_temp_storage(&old_counter_key).expect("old counter key storage not found"); + assert_eq!(markets_count, old_markets_count); Ok(()) } } #[cfg(test)] -mod tests_auto_resolution { +mod tests_authorized { use super::*; use crate::{ - mock::{ExtBuilder, Runtime}, - MomentOf, - }; - use frame_support::BoundedVec; - use zeitgeist_primitives::types::{ - Deadlines, MarketCreation, MarketDisputeMechanism, MarketId, MarketPeriod, MarketStatus, - MarketType, OutcomeReport, Report, ScoringRule, + mock::{ExtBuilder, MarketCommons, Runtime, ALICE, BOB}, + CacheSize, MarketIdOf, }; - use zrml_market_commons::Markets; - - type Market = zeitgeist_primitives::types::Market< - ::AccountId, - ::BlockNumber, - MomentOf, - >; + use frame_support::{BoundedVec, Twox64Concat}; + use zeitgeist_primitives::types::{MarketId, OutcomeReport}; + use zrml_market_commons::MarketCommonsPalletApi; #[test] fn on_runtime_upgrade_increments_the_storage_versions() { ExtBuilder::default().build().execute_with(|| { set_up_chain(); - UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); - let prediction_markets_version = StorageVersion::get::>(); - assert_eq!(prediction_markets_version, PREDICTION_MARKETS_NEXT_STORAGE_VERSION); - }); - } - - #[test] - fn on_runtime_updates_market_ids_per_dispute_block_authorized_ids_full() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - - let market_id = MarketId::from(0u64); - let market = get_market(MarketDisputeMechanism::Authorized); - - Markets::::insert(market_id, market); - - >::set_block_number(42u32.into()); - - let now = >::block_number(); - crate::MarketIdsPerDisputeBlock::::insert( - now, - BoundedVec::try_from(vec![market_id]).unwrap(), - ); - - let resolve_at = - now.saturating_add(::ReportPeriod::get()); - - let full_ids: Vec = (MarketId::from(1u64)..=MarketId::from(64u64)).collect(); - - for id in full_ids.clone() { - let market = get_market(MarketDisputeMechanism::SimpleDisputes); - Markets::::insert(id, market); - } - - crate::MarketIdsPerDisputeBlock::::insert( - resolve_at, - BoundedVec::try_from(full_ids.clone()).unwrap(), - ); - assert!(crate::MarketIdsPerDisputeBlock::::get(resolve_at).is_full()); - - UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); - - assert_eq!(crate::MarketIdsPerDisputeBlock::::get(resolve_at), full_ids); - assert!( - !crate::MarketIdsPerDisputeBlock::::get(resolve_at).contains(&market_id) - ); - // store market id at the next block - assert_eq!( - crate::MarketIdsPerDisputeBlock::::get(resolve_at + 1), - vec![market_id] - ); - }); - } - - #[test] - fn on_runtime_updates_market_ids_per_dispute_block_simple_disputes_unchanged() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - - let market_id = MarketId::from(0u64); - let market = get_market(MarketDisputeMechanism::SimpleDisputes); - - Markets::::insert(market_id, market); - - crate::MarketIdsPerDisputeBlock::::insert( - 0, - BoundedVec::try_from(vec![market_id]).unwrap(), - ); - - UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); - - // unchanged for simple disputes - assert_eq!(crate::MarketIdsPerDisputeBlock::::get(0), vec![market_id]); + AddFieldToAuthorityReport::::on_runtime_upgrade(); + let authorized_version = StorageVersion::get::>(); + assert_eq!(authorized_version, AUTHORIZED_NEXT_STORAGE_VERSION); }); } #[test] - fn on_runtime_updates_market_ids_per_dispute_block_authorized_deleted() { + fn on_runtime_sets_new_struct_with_resolve_at() { ExtBuilder::default().build().execute_with(|| { set_up_chain(); - let market_id = MarketId::from(0u64); - let market = get_market(MarketDisputeMechanism::Authorized); + >::set_block_number(10_000); - Markets::::insert(market_id, market); - - crate::MarketIdsPerDisputeBlock::::insert( - 0, - BoundedVec::try_from(vec![market_id]).unwrap(), + let hash = crate::migrations::utility::key_to_hash::(0); + let outcome = OutcomeReport::Categorical(42u16); + put_storage_value::>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &hash, + Some(outcome.clone()), ); - UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + let resolve_at = 42_000; - // authority controls market resolution now (no auto resolution) - assert!(crate::MarketIdsPerDisputeBlock::::get(0).is_empty()); - }); - } + let sample_market = get_sample_market(); + let market_id: MarketId = MarketCommons::push_market(sample_market).unwrap(); + let bounded_vec = + BoundedVec::, CacheSize>::try_from(vec![market_id]) + .expect("BoundedVec should be created"); + crate::MarketIdsPerDisputeBlock::::insert(resolve_at, bounded_vec); - #[test] - fn on_runtime_updates_market_ids_per_dispute_block_court_deletion() { - ExtBuilder::default().build().execute_with(|| { - set_up_chain(); - - let market_id = MarketId::from(0u64); - let market = get_market(MarketDisputeMechanism::Court); - Markets::::insert(market_id, market); - - crate::MarketIdsPerDisputeBlock::::insert( - 0, - BoundedVec::try_from(vec![market_id]).unwrap(), - ); + AddFieldToAuthorityReport::::on_runtime_upgrade(); - UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + let expected = Some(AuthorityReport { resolve_at, outcome }); - // court auto resolution is deactivated for now (court is disabled) - assert!(crate::MarketIdsPerDisputeBlock::::get(0).is_empty()); + let actual = frame_support::migration::get_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) + .unwrap(); + assert_eq!(expected, actual); }); } #[test] fn on_runtime_is_noop_if_versions_are_not_correct() { ExtBuilder::default().build().execute_with(|| { - // Don't set up chain to signal that storage is already up to date. + // storage migration already executed (storage version is incremented already) + StorageVersion::new(AUTHORIZED_NEXT_STORAGE_VERSION).put::>(); - let market_id = MarketId::from(0u64); - let market = get_market(MarketDisputeMechanism::Court); - Markets::::insert(market_id, market); + let hash = crate::migrations::utility::key_to_hash::(0); + let outcome = OutcomeReport::Categorical(42u16); - crate::MarketIdsPerDisputeBlock::::insert( - 0, - BoundedVec::try_from(vec![market_id]).unwrap(), - ); + let report = AuthorityReport { resolve_at: 42, outcome }; + put_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, Some(report.clone())); - UpdateMarketIdsPerDisputeBlock::::on_runtime_upgrade(); + AddFieldToAuthorityReport::::on_runtime_upgrade(); - // normally court auto resolution gets deleted with the storage migration, - // but because storage version is already updated, - // it is not - assert_eq!(crate::MarketIdsPerDisputeBlock::::get(0), vec![market_id]); + let actual = frame_support::migration::get_storage_value::< + Option::BlockNumber>>, + >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) + .unwrap(); + assert_eq!(Some(report), actual); }); } - fn get_market(mdm: MarketDisputeMechanism) -> Market { - Market { - creator: 1, - creation: MarketCreation::Permissionless, - creator_fee: 2, - oracle: 3, - metadata: vec![4, 5], - market_type: MarketType::Categorical(14), - period: MarketPeriod::Block(6..7), - deadlines: Deadlines { grace_period: 8, oracle_duration: 9, dispute_duration: 10 }, - scoring_rule: ScoringRule::CPMM, - status: MarketStatus::Disputed, - report: Some(Report { at: 11, by: 12, outcome: OutcomeReport::Categorical(13) }), - resolved_outcome: Some(OutcomeReport::Categorical(13)), - dispute_mechanism: mdm, - } + fn set_up_chain() { + StorageVersion::new(AUTHORIZED_REQUIRED_STORAGE_VERSION).put::>(); } - fn set_up_chain() { - StorageVersion::new(PREDICTION_MARKETS_REQUIRED_STORAGE_VERSION).put::>(); + fn get_sample_market() -> zeitgeist_primitives::types::Market { + zeitgeist_primitives::types::Market { + creation: zeitgeist_primitives::types::MarketCreation::Permissionless, + creator_fee: 0, + creator: ALICE, + market_type: zeitgeist_primitives::types::MarketType::Scalar(0..=100), + dispute_mechanism: zeitgeist_primitives::types::MarketDisputeMechanism::Authorized, + metadata: Default::default(), + oracle: BOB, + period: zeitgeist_primitives::types::MarketPeriod::Block(Default::default()), + deadlines: zeitgeist_primitives::types::Deadlines { + grace_period: 1_u32.into(), + oracle_duration: 1_u32.into(), + dispute_duration: 1_u32.into(), + }, + report: None, + resolved_outcome: None, + scoring_rule: zeitgeist_primitives::types::ScoringRule::CPMM, + status: zeitgeist_primitives::types::MarketStatus::Disputed, + } } } -// We use these utilities to prevent having to make the swaps pallet a dependency of -// prediciton-markets. The calls are based on the implementation of `StorageVersion`, found here: -// https://github.com/paritytech/substrate/blob/bc7a1e6c19aec92bfa247d8ca68ec63e07061032/frame/support/src/traits/metadata.rs#L168-L230 -// and previous migrations. mod utility { use crate::{BalanceOf, Config, MarketIdOf}; use alloc::vec::Vec; From eb7b5332245b882c8674a400bad8f909bfced219 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 22 Dec 2022 08:21:57 +0100 Subject: [PATCH 73/93] remove fallible authority feature --- primitives/src/constants/mock.rs | 1 - runtime/battery-station/src/parameters.rs | 1 - runtime/common/src/lib.rs | 1 - runtime/zeitgeist/src/parameters.rs | 1 - zrml/authorized/src/lib.rs | 33 +-------- zrml/authorized/src/mock.rs | 3 +- zrml/authorized/src/tests.rs | 85 +---------------------- zrml/prediction-markets/src/benchmarks.rs | 14 ---- zrml/prediction-markets/src/lib.rs | 1 - zrml/prediction-markets/src/mock.rs | 6 +- 10 files changed, 7 insertions(+), 139 deletions(-) diff --git a/primitives/src/constants/mock.rs b/primitives/src/constants/mock.rs index f6f30d0d9..7c47a8094 100644 --- a/primitives/src/constants/mock.rs +++ b/primitives/src/constants/mock.rs @@ -10,7 +10,6 @@ use orml_traits::parameter_type_with_key; // Authorized parameter_types! { - pub const ReportPeriod: BlockNumber = 10; pub const AuthorizedPalletId: PalletId = PalletId(*b"zge/atzd"); pub const CorrectionPeriod: BlockNumber = 4; } diff --git a/runtime/battery-station/src/parameters.rs b/runtime/battery-station/src/parameters.rs index 0ab103b55..f392555e4 100644 --- a/runtime/battery-station/src/parameters.rs +++ b/runtime/battery-station/src/parameters.rs @@ -50,7 +50,6 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized - pub const ReportPeriod: BlockNumber = 6 * BLOCKS_PER_DAY; pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; pub const CorrectionPeriod: BlockNumber = 3 * BLOCKS_PER_HOUR; diff --git a/runtime/common/src/lib.rs b/runtime/common/src/lib.rs index b0a64b076..6f80b8b5e 100644 --- a/runtime/common/src/lib.rs +++ b/runtime/common/src/lib.rs @@ -922,7 +922,6 @@ macro_rules! impl_config_traits { type Event = Event; type MarketCommons = MarketCommons; type PalletId = AuthorizedPalletId; - type ReportPeriod = ReportPeriod; type WeightInfo = zrml_authorized::weights::WeightInfo; } diff --git a/runtime/zeitgeist/src/parameters.rs b/runtime/zeitgeist/src/parameters.rs index f5068690b..40184a246 100644 --- a/runtime/zeitgeist/src/parameters.rs +++ b/runtime/zeitgeist/src/parameters.rs @@ -50,7 +50,6 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized - pub const ReportPeriod: BlockNumber = 6 * BLOCKS_PER_DAY; pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; pub const CorrectionPeriod: BlockNumber = 6 * BLOCKS_PER_HOUR; diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 152814741..3403d8085 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -94,13 +94,7 @@ mod pallet { #[cfg(test)] let fallible_authority = true; - if fallible_authority { - let disputes = T::DisputeResolution::get_disputes(&market_id); - if let Some(dispute) = disputes.last() { - let not_expired = !Self::has_expired(dispute.at); - ensure!(not_expired, Error::::ReportPeriodExpired); - } - } + if fallible_authority {} let ids_len_1 = Self::remove_auto_resolve(&market_id); let now = frame_system::Pallet::::block_number(); @@ -117,12 +111,6 @@ mod pallet { #[pallet::config] pub trait Config: frame_system::Config { - /// In case the authority is a simple account: - /// The period in which the authority has to report. This value must not be zero. - /// This value should be fairly large, so that the authority has enough time to report. - #[pallet::constant] - type ReportPeriod: Get; - /// Event type Event: From> + IsType<::Event>; @@ -160,8 +148,6 @@ mod pallet { MarketDoesNotHaveDisputeMechanismAuthorized, /// An account attempts to submit a report to an undisputed market. MarketIsNotDisputed, - /// The report period is expired. - ReportPeriodExpired, /// Only one dispute is allowed. OnlyOneDisputeAllowed, /// The report does not match the market's type. @@ -200,11 +186,6 @@ mod pallet { 0u32 } } - - fn has_expired(start: T::BlockNumber) -> bool { - let now = frame_system::Pallet::::block_number(); - start.saturating_add(T::ReportPeriod::get()) < now - } } impl DisputeApi for Pallet @@ -260,7 +241,7 @@ mod pallet { } fn has_failed( - disputes: &[MarketDispute], + _: &[MarketDispute], _: &Self::MarketId, market: &Market>, ) -> Result { @@ -269,16 +250,6 @@ mod pallet { Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - // TODO (#918): when we later allow a simple account id to be the authority, this expiration limit becomes useful - #[cfg(not(test))] - let fallible_authority = false; - #[cfg(test)] - let fallible_authority = true; - if fallible_authority { - let last_dispute = disputes.last().ok_or(Error::::MarketIsNotDisputed)?; - return Ok(Self::has_expired(last_dispute.at)); - } - Ok(false) } } diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index eff0125e2..281fbd3d4 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -35,7 +35,7 @@ use sp_runtime::{ use zeitgeist_primitives::{ constants::mock::{ AuthorizedPalletId, BlockHashCount, CorrectionPeriod, MaxReserves, MinimumPeriod, - PmPalletId, ReportPeriod, BASE, + PmPalletId, BASE, }, traits::DisputeResolutionApi, types::{ @@ -129,7 +129,6 @@ impl DisputeResolutionApi for MockResolution { } impl crate::Config for Runtime { - type ReportPeriod = ReportPeriod; type Event = (); type CorrectionPeriod = CorrectionPeriod; type DisputeResolution = MockResolution; diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index 2b3d65c66..0808e2d6b 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -25,8 +25,8 @@ use crate::{ }; use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; use zeitgeist_primitives::{ - traits::{DisputeApi, DisputeResolutionApi}, - types::{AuthorityReport, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport}, + traits::DisputeApi, + types::{AuthorityReport, MarketDisputeMechanism, MarketStatus, OutcomeReport}, }; use zrml_market_commons::Markets; @@ -254,84 +254,3 @@ fn get_auto_resolve_returns_none_without_market_storage() { assert_eq!(Authorized::get_auto_resolve(&[], &0, &market).unwrap(), None,); }); } - -#[test] -fn has_failed_works_without_report() { - ExtBuilder::default().build().execute_with(|| { - frame_system::Pallet::::set_block_number(42); - let market = market_mock::(); - Markets::::insert(0, &market); - let now = frame_system::Pallet::::block_number(); - let last_dispute = MarketDispute { at: now, by: BOB, outcome: OutcomeReport::Scalar(1) }; - - assert!(!Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); - - frame_system::Pallet::::set_block_number( - now + ::ReportPeriod::get() + 1, - ); - - assert!(Authorized::has_failed(&[last_dispute], &0, &market).unwrap()); - }); -} - -#[test] -fn has_failed_works_with_renewed_reports() { - ExtBuilder::default().build().execute_with(|| { - frame_system::Pallet::::set_block_number(42); - let market = market_mock::(); - Markets::::insert(0, &market); - let now = frame_system::Pallet::::block_number(); - let last_dispute = MarketDispute { at: now, by: BOB, outcome: OutcomeReport::Scalar(1) }; - - // assume `authorize_market_outcome` is renewed indefintiely - // by a fallible authority (one account id) - assert_ok!(Authorized::authorize_market_outcome( - Origin::signed(AuthorizedDisputeResolutionUser::get()), - 0, - OutcomeReport::Scalar(1) - )); - - frame_system::Pallet::::set_block_number( - now + ::ReportPeriod::get() - 1, - ); - - assert!(!Authorized::has_failed(&[last_dispute.clone()], &0, &market).unwrap()); - - frame_system::Pallet::::set_block_number( - now + ::ReportPeriod::get() + 1, - ); - - assert!(Authorized::has_failed(&[last_dispute], &0, &market).unwrap()); - }); -} - -#[test] -fn authorize_market_outcome_fails_with_report_period_expired() { - ExtBuilder::default().build().execute_with(|| { - frame_system::Pallet::::set_block_number(42); - let market = market_mock::(); - Markets::::insert(0, &market); - - let dispute_at = 42; - let last_dispute = - MarketDispute { at: dispute_at, by: BOB, outcome: OutcomeReport::Scalar(42) }; - // get_disputes returns a sample dispute in the mock - assert_eq!( - ::DisputeResolution::get_disputes(&0).pop().unwrap(), - last_dispute - ); - - frame_system::Pallet::::set_block_number( - dispute_at + ::ReportPeriod::get() + 1, - ); - - assert_noop!( - Authorized::authorize_market_outcome( - Origin::signed(AuthorizedDisputeResolutionUser::get()), - 0, - OutcomeReport::Scalar(1) - ), - Error::::ReportPeriodExpired - ); - }); -} diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 968c1228a..1127e4c11 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -890,13 +890,6 @@ benchmarks! { T::AssetManager::deposit(Asset::Ztg, &disputor, (u128::MAX).saturated_into())?; Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; - let authority_report_period = ::ReportPeriod::get(); - let now = >::block_number(); - // authorized mdm fails after the ReportPeriod - >::set_block_number( - now + authority_report_period.saturated_into() + 1u64.saturated_into() - ); - let call = Call::::resolve_failed_mdm { market_id }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; @@ -928,13 +921,6 @@ benchmarks! { )?; Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; - let authority_report_period = ::ReportPeriod::get(); - let now = >::block_number(); - // authorized mdm fails after the ReportPeriod - >::set_block_number( - now + authority_report_period.saturated_into() + 1u64.saturated_into() - ); - let call = Call::::resolve_failed_mdm { market_id }; }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index c47064d18..a6f625222 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -521,7 +521,6 @@ mod pallet { }; // TODO (#918): benchmarks only reach the end when a dispute mechanism has failed - #[cfg(feature = "runtime-benchmarks")] let _has_failed = true; ensure!(_has_failed, Error::::DisputeMechanismHasNotFailed); diff --git a/zrml/prediction-markets/src/mock.rs b/zrml/prediction-markets/src/mock.rs index 515f80818..f44b7b8ba 100644 --- a/zrml/prediction-markets/src/mock.rs +++ b/zrml/prediction-markets/src/mock.rs @@ -42,9 +42,8 @@ use zeitgeist_primitives::{ MaxInRatio, MaxMarketPeriod, MaxOracleDuration, MaxOutRatio, MaxRejectReasonLen, MaxReserves, MaxSubsidyPeriod, MaxSwapFee, MaxTotalWeight, MaxWeight, MinAssets, MinCategories, MinDisputeDuration, MinLiquidity, MinOracleDuration, MinSubsidy, - MinSubsidyPeriod, MinWeight, MinimumPeriod, PmPalletId, ReportPeriod, - SimpleDisputesPalletId, StakeWeight, SwapsPalletId, TreasuryPalletId, BASE, CENT, - MILLISECS_PER_BLOCK, + MinSubsidyPeriod, MinWeight, MinimumPeriod, PmPalletId, SimpleDisputesPalletId, + StakeWeight, SwapsPalletId, TreasuryPalletId, BASE, CENT, MILLISECS_PER_BLOCK, }, types::{ AccountIdTest, Amount, Asset, Balance, BasicCurrencyAdapter, BlockNumber, BlockTest, @@ -253,7 +252,6 @@ ord_parameter_types! { } impl zrml_authorized::Config for Runtime { - type ReportPeriod = ReportPeriod; type AuthorizedDisputeResolutionOrigin = EnsureSignedBy; type CorrectionPeriod = CorrectionPeriod; From 05fdef78e056b0f865603eb9bd01b091b2b732f3 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 22 Dec 2022 08:25:42 +0100 Subject: [PATCH 74/93] remove fallible authority feature --- zrml/authorized/src/lib.rs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 3403d8085..2627e0143 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -88,14 +88,6 @@ mod pallet { Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - // TODO (#918): when we later allow a simple account id to be the authority, this expiration limit becomes useful - #[cfg(not(test))] - let fallible_authority = false; - #[cfg(test)] - let fallible_authority = true; - - if fallible_authority {} - let ids_len_1 = Self::remove_auto_resolve(&market_id); let now = frame_system::Pallet::::block_number(); let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); From 9d8d3cbea6a8722b3bbced80e0e53670fb196f3b Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 2 Jan 2023 14:18:29 +0100 Subject: [PATCH 75/93] avoid option storage query, handle 432 market --- zrml/prediction-markets/src/migrations.rs | 94 +++++++++++++---------- 1 file changed, 55 insertions(+), 39 deletions(-) diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index f9312e6ee..6dd3e339a 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -37,6 +37,7 @@ use frame_support::{ use frame_system::pallet_prelude::BlockNumberFor; #[cfg(feature = "try-runtime")] use scale_info::prelude::format; +use sp_runtime::traits::Zero; use zeitgeist_primitives::types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}; use zrml_authorized::Pallet as AuthorizedPallet; use zrml_market_commons::MarketCommonsPalletApi; @@ -89,21 +90,42 @@ impl OnRuntim ::MarketId, AuthorityReport>, )> = Vec::new(); + for (market_id, old_value) in storage_key_iter::< ::MarketId, - Option, + OutcomeReport, Twox64Concat, >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); - if let Some(outcome) = old_value { - let resolve_at: BlockNumberFor = *authorized_resolutions.get(&market_id).expect( - "For every market id in authorized_resolutions, there needs to be an \ - authorized outcome report!", - ); + let resolve_at: Option> = + authorized_resolutions.get(&market_id).cloned(); - new_storage_map.push((market_id, AuthorityReport { resolve_at, outcome })); + match resolve_at { + Some(block) => { + new_storage_map.push(( + market_id, + AuthorityReport { resolve_at: block, outcome: old_value }, + )); + } + None => { + log::warn!( + "AddFieldToAuthorityReport: Market was not found in \ + MarketIdsPerDisputeBlock; market id: {:?}", + market_id + ); + // example case market id 432 + // https://github.com/zeitgeistpm/zeitgeist/pull/701 market id 432 is invalid, because of zero-division error in the past + // we have to handle manually here, because MarketIdsPerDisputeBlock does not contain 432 + new_storage_map.push(( + market_id, + AuthorityReport { + resolve_at: >::zero(), + outcome: old_value, + }, + )); + } } } @@ -112,11 +134,11 @@ impl OnRuntim Twox64Concat, ::MarketId, >(market_id); - put_storage_value::>>( + put_storage_value::>( AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, - Some(new_value), + new_value, ); total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); } @@ -132,9 +154,7 @@ impl OnRuntim use frame_support::traits::OnRuntimeUpgradeHelpersExt; let mut counter = 0_u32; - for (key, value) in - storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) - { + for (key, value) in storage_iter::(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { Self::set_temp_storage(value, &format!("{:?}", key.as_slice())); counter = counter.saturating_add(1_u32); @@ -149,25 +169,18 @@ impl OnRuntim use frame_support::traits::OnRuntimeUpgradeHelpersExt; let mut markets_count = 0_u32; let old_counter_key = "counter_key".to_string(); - for (key, new_value) in storage_iter::>>( - AUTHORIZED, - AUTHORIZED_OUTCOME_REPORTS, - ) { + for (key, new_value) in + storage_iter::>(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) + { let key_str = format!("{:?}", key.as_slice()); - if let Some(AuthorityReport { resolve_at: _, outcome }) = new_value { - let old_value: Option = Self::get_temp_storage(&key_str) - .unwrap_or_else(|| panic!("old value not found for market id {:?}", key_str)); - - assert_eq!(old_value.unwrap(), outcome); - - markets_count += 1_u32; - } else { - panic!( - "For market id {:?} storage iter should only find present (Option::Some) \ - values", - key_str - ); - } + + let AuthorityReport { resolve_at: _, outcome } = new_value; + let old_value: OutcomeReport = Self::get_temp_storage(&key_str) + .unwrap_or_else(|| panic!("old value not found for market id {:?}", key_str)); + + assert_eq!(old_value, outcome); + + markets_count += 1_u32; } let old_markets_count: u32 = Self::get_temp_storage(&old_counter_key).expect("old counter key storage not found"); @@ -206,11 +219,11 @@ mod tests_authorized { let hash = crate::migrations::utility::key_to_hash::(0); let outcome = OutcomeReport::Categorical(42u16); - put_storage_value::>( + put_storage_value::( AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, - Some(outcome.clone()), + outcome.clone(), ); let resolve_at = 42_000; @@ -224,10 +237,10 @@ mod tests_authorized { AddFieldToAuthorityReport::::on_runtime_upgrade(); - let expected = Some(AuthorityReport { resolve_at, outcome }); + let expected = AuthorityReport { resolve_at, outcome }; let actual = frame_support::migration::get_storage_value::< - Option::BlockNumber>>, + AuthorityReport<::BlockNumber>, >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) .unwrap(); assert_eq!(expected, actual); @@ -244,17 +257,20 @@ mod tests_authorized { let outcome = OutcomeReport::Categorical(42u16); let report = AuthorityReport { resolve_at: 42, outcome }; - put_storage_value::< - Option::BlockNumber>>, - >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash, Some(report.clone())); + put_storage_value::::BlockNumber>>( + AUTHORIZED, + AUTHORIZED_OUTCOME_REPORTS, + &hash, + report.clone(), + ); AddFieldToAuthorityReport::::on_runtime_upgrade(); let actual = frame_support::migration::get_storage_value::< - Option::BlockNumber>>, + AuthorityReport<::BlockNumber>, >(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS, &hash) .unwrap(); - assert_eq!(Some(report), actual); + assert_eq!(report, actual); }); } From c127139447bbc10c7615bd8dedc5972d79bf7b54 Mon Sep 17 00:00:00 2001 From: Chralt Date: Wed, 4 Jan 2023 09:45:25 +0100 Subject: [PATCH 76/93] Update zrml/authorized/src/mock_storage.rs Co-authored-by: Malte Kliemann --- zrml/authorized/src/mock_storage.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/zrml/authorized/src/mock_storage.rs b/zrml/authorized/src/mock_storage.rs index 96dc6fd56..c7908fa55 100644 --- a/zrml/authorized/src/mock_storage.rs +++ b/zrml/authorized/src/mock_storage.rs @@ -1,4 +1,4 @@ -// Copyright 2021-2022 Zeitgeist PM LLC. +// Copyright 2022 Forecasting Technologies LTD. // // This file is part of Zeitgeist. // From 9aa93c41501312977292171937fdd1ead112a2f5 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 4 Jan 2023 09:55:00 +0100 Subject: [PATCH 77/93] fix resolve_failed_mdm bug --- zrml/prediction-markets/src/lib.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index a6f625222..c47064d18 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -521,6 +521,7 @@ mod pallet { }; // TODO (#918): benchmarks only reach the end when a dispute mechanism has failed + #[cfg(feature = "runtime-benchmarks")] let _has_failed = true; ensure!(_has_failed, Error::::DisputeMechanismHasNotFailed); From c4b623a87163f918663819d692b6473fb1e214d7 Mon Sep 17 00:00:00 2001 From: Chralt Date: Wed, 4 Jan 2023 10:52:03 +0100 Subject: [PATCH 78/93] Update zrml/prediction-markets/src/tests.rs Co-authored-by: Malte Kliemann --- zrml/prediction-markets/src/tests.rs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 164f504e5..2ae61c998 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -2051,12 +2051,6 @@ fn dispute_fails_authority_reported_already() { OutcomeReport::Categorical(0) )); - assert_ok!(Authorized::authorize_market_outcome( - Origin::signed(AuthorizedDisputeResolutionUser::get()), - 0, - OutcomeReport::Categorical(0) - )); - assert_noop!( PredictionMarkets::dispute(Origin::signed(CHARLIE), 0, OutcomeReport::Categorical(1)), AuthorizedError::::OnlyOneDisputeAllowed From 532b68622acbef3de5963e2afbe81ebd37c92bc3 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 4 Jan 2023 11:26:04 +0100 Subject: [PATCH 79/93] fixes after merge --- primitives/src/traits/dispute_api.rs | 14 ++++++-- zrml/authorized/src/lib.rs | 6 ++-- zrml/authorized/src/mock.rs | 3 +- zrml/court/src/lib.rs | 4 +-- zrml/court/src/mock.rs | 3 +- zrml/prediction-markets/src/lib.rs | 3 +- zrml/prediction-markets/src/migrations.rs | 44 +++++++---------------- zrml/simple-disputes/src/lib.rs | 10 +++--- zrml/simple-disputes/src/mock.rs | 3 +- 9 files changed, 41 insertions(+), 49 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index 9dfce5853..c49693b8d 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -70,7 +70,7 @@ pub trait DisputeApi { fn get_auto_resolve( disputes: &[MarketDispute], market_id: &Self::MarketId, - market: &Market, + market: &MarketOfDisputeApi, ) -> Result, DispatchError>; /// Returns `true` if the market dispute mechanism @@ -79,12 +79,20 @@ pub trait DisputeApi { fn has_failed( disputes: &[MarketDispute], market_id: &Self::MarketId, - market: &Market, + market: &MarketOfDisputeApi, ) -> Result; } +type MarketOfDisputeResolutionApi = Market< + ::AccountId, + ::Balance, + ::BlockNumber, + ::Moment, +>; + pub trait DisputeResolutionApi { type AccountId; + type Balance; type BlockNumber; type MarketId; type MaxDisputes; @@ -100,7 +108,7 @@ pub trait DisputeResolutionApi { /// Returns the consumed weight. fn resolve( market_id: &Self::MarketId, - market: &Market, + market: &MarketOfDisputeResolutionApi, ) -> Result; /// Add a future block resolution of a disputed market. diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index eb60b047d..03f52b7a3 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -65,7 +65,7 @@ mod pallet { pub(crate) type MomentOf = <::MarketCommons as MarketCommonsPalletApi>::Moment; pub type CacheSize = ConstU32<64>; - type MarketOf = Market< + pub(crate) type MarketOf = Market< ::AccountId, BalanceOf, ::BlockNumber, @@ -229,7 +229,7 @@ mod pallet { fn get_auto_resolve( _: &[MarketDispute], market_id: &Self::MarketId, - market: &Market>, + market: &MarketOf, ) -> Result, DispatchError> { ensure!( market.dispute_mechanism == MarketDisputeMechanism::Authorized, @@ -241,7 +241,7 @@ mod pallet { fn has_failed( _: &[MarketDispute], _: &Self::MarketId, - market: &Market>, + market: &MarketOf, ) -> Result { ensure!( market.dispute_mechanism == MarketDisputeMechanism::Authorized, diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 281fbd3d4..966f417c6 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -83,6 +83,7 @@ pub struct MockResolution; impl DisputeResolutionApi for MockResolution { type AccountId = AccountIdTest; + type Balance = Balance; type BlockNumber = BlockNumber; type MarketId = MarketId; type MaxDisputes = MaxDisputesTest; @@ -90,7 +91,7 @@ impl DisputeResolutionApi for MockResolution { fn resolve( _market_id: &Self::MarketId, - _market: &Market, + _market: &Market, ) -> Result { Ok(0) } diff --git a/zrml/court/src/lib.rs b/zrml/court/src/lib.rs index 3192971d0..c1d08183b 100644 --- a/zrml/court/src/lib.rs +++ b/zrml/court/src/lib.rs @@ -566,7 +566,7 @@ mod pallet { fn get_auto_resolve( _: &[MarketDispute], _: &Self::MarketId, - market: &Market>, + market: &MarketOf, ) -> Result, DispatchError> { ensure!( market.dispute_mechanism == MarketDisputeMechanism::Court, @@ -578,7 +578,7 @@ mod pallet { fn has_failed( _: &[MarketDispute], _: &Self::MarketId, - market: &Market>, + market: &MarketOf, ) -> Result { ensure!( market.dispute_mechanism == MarketDisputeMechanism::Court, diff --git a/zrml/court/src/mock.rs b/zrml/court/src/mock.rs index 7ca34ff28..338defd91 100644 --- a/zrml/court/src/mock.rs +++ b/zrml/court/src/mock.rs @@ -71,6 +71,7 @@ pub struct NoopResolution; impl DisputeResolutionApi for NoopResolution { type AccountId = AccountIdTest; + type Balance = Balance; type BlockNumber = BlockNumber; type MarketId = MarketId; type MaxDisputes = u32; @@ -78,7 +79,7 @@ impl DisputeResolutionApi for NoopResolution { fn resolve( _market_id: &Self::MarketId, - _market: &Market, + _market: &Market, ) -> Result { Ok(0) } diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 8a19266d9..452b7a3a5 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -2946,6 +2946,7 @@ mod pallet { T: Config, { type AccountId = T::AccountId; + type Balance = BalanceOf; type BlockNumber = T::BlockNumber; type MarketId = MarketIdOf; type MaxDisputes = T::MaxDisputes; @@ -2953,7 +2954,7 @@ mod pallet { fn resolve( market_id: &Self::MarketId, - market: &Market, + market: &Market, ) -> Result { Self::on_resolution(market_id, market) } diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index 0df3484d8..b897cdadc 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -19,10 +19,8 @@ use crate::MarketIdOf; use crate::{Config, MarketOf, MomentOf}; #[cfg(feature = "try-runtime")] -use alloc::collections::BTreeMap; -#[cfg(feature = "try-runtime")] use alloc::format; -use alloc::vec::Vec; +use alloc::{collections::BTreeMap, vec::Vec}; #[cfg(feature = "try-runtime")] use frame_support::traits::OnRuntimeUpgradeHelpersExt; use frame_support::{ @@ -39,9 +37,7 @@ use zeitgeist_primitives::types::{ Bond, Deadlines, Market, MarketBonds, MarketCreation, MarketDisputeMechanism, MarketPeriod, MarketStatus, MarketType, OutcomeReport, Report, ScoringRule, }; -#[cfg(feature = "try-runtime")] -use zrml_market_commons::MarketCommonsPalletApi; -use zrml_market_commons::Pallet as MarketCommonsPallet; +use zrml_market_commons::{MarketCommonsPalletApi, Pallet as MarketCommonsPallet}; const MARKET_COMMONS: &[u8] = b"MarketCommons"; const MARKETS: &[u8] = b"Markets"; @@ -146,7 +142,7 @@ impl OnRuntimeUpgrade for RecordBonds Result<(), &'static str> { - use frame_support::{migration::storage_key_iter, pallet_prelude::Blake2_128Concat}; + use frame_support::pallet_prelude::Blake2_128Concat; let old_markets = storage_key_iter::, OldMarketOf, Blake2_128Concat>( MARKET_COMMONS, @@ -424,32 +420,13 @@ mod tests { } } -// We use these utilities to prevent having to make the swaps pallet a dependency of -// prediciton-markets. The calls are based on the implementation of `StorageVersion`, found here: -// https://github.com/paritytech/substrate/blob/bc7a1e6c19aec92bfa247d8ca68ec63e07061032/frame/support/src/traits/metadata.rs#L168-L230 -// and previous migrations. - -use crate::Config; #[cfg(feature = "try-runtime")] use alloc::string::ToString; -use alloc::{collections::BTreeMap, vec::Vec}; -#[cfg(feature = "try-runtime")] -use frame_support::migration::storage_iter; -use frame_support::{ - dispatch::Weight, - log, - migration::{put_storage_value, storage_key_iter}, - pallet_prelude::PhantomData, - traits::{Get, OnRuntimeUpgrade, StorageVersion}, - Twox64Concat, -}; +use frame_support::{migration::storage_key_iter, Twox64Concat}; use frame_system::pallet_prelude::BlockNumberFor; -#[cfg(feature = "try-runtime")] -use scale_info::prelude::format; use sp_runtime::traits::Zero; -use zeitgeist_primitives::types::{AuthorityReport, MarketDisputeMechanism, OutcomeReport}; +use zeitgeist_primitives::types::AuthorityReport; use zrml_authorized::Pallet as AuthorizedPallet; -use zrml_market_commons::MarketCommonsPalletApi; const AUTHORIZED: &[u8] = b"Authorized"; const AUTHORIZED_OUTCOME_REPORTS: &[u8] = b"AuthorizedOutcomeReports"; @@ -560,8 +537,6 @@ impl OnRuntim #[cfg(feature = "try-runtime")] fn pre_upgrade() -> Result<(), &'static str> { - use frame_support::traits::OnRuntimeUpgradeHelpersExt; - let mut counter = 0_u32; for (key, value) in storage_iter::(AUTHORIZED, AUTHORIZED_OUTCOME_REPORTS) { Self::set_temp_storage(value, &format!("{:?}", key.as_slice())); @@ -575,7 +550,6 @@ impl OnRuntim #[cfg(feature = "try-runtime")] fn post_upgrade() -> Result<(), &'static str> { - use frame_support::traits::OnRuntimeUpgradeHelpersExt; let mut markets_count = 0_u32; let old_counter_key = "counter_key".to_string(); for (key, new_value) in @@ -687,7 +661,7 @@ mod tests_authorized { StorageVersion::new(AUTHORIZED_REQUIRED_STORAGE_VERSION).put::>(); } - fn get_sample_market() -> zeitgeist_primitives::types::Market { + fn get_sample_market() -> zeitgeist_primitives::types::Market { zeitgeist_primitives::types::Market { creation: zeitgeist_primitives::types::MarketCreation::Permissionless, creator_fee: 0, @@ -706,10 +680,16 @@ mod tests_authorized { resolved_outcome: None, scoring_rule: zeitgeist_primitives::types::ScoringRule::CPMM, status: zeitgeist_primitives::types::MarketStatus::Disputed, + bonds: Default::default(), } } } +// We use these utilities to prevent having to make the swaps pallet a dependency of +// prediciton-markets. The calls are based on the implementation of `StorageVersion`, found here: +// https://github.com/paritytech/substrate/blob/bc7a1e6c19aec92bfa247d8ca68ec63e07061032/frame/support/src/traits/metadata.rs#L168-L230 +// and previous migrations. + mod utility { use crate::{BalanceOf, Config, MarketIdOf}; use alloc::vec::Vec; diff --git a/zrml/simple-disputes/src/lib.rs b/zrml/simple-disputes/src/lib.rs index fc6691ee6..193a3f716 100644 --- a/zrml/simple-disputes/src/lib.rs +++ b/zrml/simple-disputes/src/lib.rs @@ -107,7 +107,7 @@ mod pallet { { fn get_auto_resolve( disputes: &[MarketDispute], - market: &Market>, + market: &MarketOf, ) -> Option { disputes.last().map(|last_dispute| { last_dispute.at.saturating_add(market.deadlines.dispute_duration) @@ -117,7 +117,7 @@ mod pallet { fn remove_auto_resolve( disputes: &[MarketDispute], market_id: &MarketIdOf, - market: &Market>, + market: &MarketOf, ) { if let Some(dispute_duration_ends_at_block) = Self::get_auto_resolve(disputes, market) { T::DisputeResolution::remove_auto_resolve( @@ -142,7 +142,7 @@ mod pallet { fn on_dispute( disputes: &[MarketDispute], market_id: &Self::MarketId, - market: &Market>, + market: &MarketOf, ) -> DispatchResult { ensure!( market.dispute_mechanism == MarketDisputeMechanism::SimpleDisputes, @@ -178,7 +178,7 @@ mod pallet { fn get_auto_resolve( disputes: &[MarketDispute], _: &Self::MarketId, - market: &Market>, + market: &MarketOf, ) -> Result, DispatchError> { ensure!( market.dispute_mechanism == MarketDisputeMechanism::SimpleDisputes, @@ -190,7 +190,7 @@ mod pallet { fn has_failed( _: &[MarketDispute], _: &Self::MarketId, - market: &Market>, + market: &MarketOf, ) -> Result { ensure!( market.dispute_mechanism == MarketDisputeMechanism::SimpleDisputes, diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index af2b0d8d4..f1ed7aa74 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -59,6 +59,7 @@ pub struct NoopResolution; impl DisputeResolutionApi for NoopResolution { type AccountId = AccountIdTest; + type Balance = Balance; type BlockNumber = BlockNumber; type MarketId = MarketId; type MaxDisputes = u32; @@ -66,7 +67,7 @@ impl DisputeResolutionApi for NoopResolution { fn resolve( _market_id: &Self::MarketId, - _market: &Market, + _market: &Market, ) -> Result { Ok(0) } From 193dc1b63291f932a2282610321df8a60265f838 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 4 Jan 2023 14:35:35 +0100 Subject: [PATCH 80/93] avoid refreshing correction period --- runtime/battery-station/src/parameters.rs | 2 +- runtime/zeitgeist/src/parameters.rs | 2 +- zrml/authorized/src/benchmarks.rs | 47 ++++++++++++++++------- zrml/authorized/src/lib.rs | 44 +++++++++++---------- zrml/authorized/src/tests.rs | 14 +++---- zrml/authorized/src/weights.rs | 30 +++++++++------ 6 files changed, 84 insertions(+), 55 deletions(-) diff --git a/runtime/battery-station/src/parameters.rs b/runtime/battery-station/src/parameters.rs index f392555e4..ed4fd4d2d 100644 --- a/runtime/battery-station/src/parameters.rs +++ b/runtime/battery-station/src/parameters.rs @@ -51,7 +51,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; - pub const CorrectionPeriod: BlockNumber = 3 * BLOCKS_PER_HOUR; + pub const CorrectionPeriod: BlockNumber = BLOCKS_PER_DAY; // Authority pub const MaxAuthorities: u32 = 32; diff --git a/runtime/zeitgeist/src/parameters.rs b/runtime/zeitgeist/src/parameters.rs index 40184a246..060e26a5b 100644 --- a/runtime/zeitgeist/src/parameters.rs +++ b/runtime/zeitgeist/src/parameters.rs @@ -51,7 +51,7 @@ pub(crate) const FEES_AND_TIPS_BURN_PERCENTAGE: u32 = 0; parameter_types! { // Authorized pub const AuthorizedPalletId: PalletId = AUTHORIZED_PALLET_ID; - pub const CorrectionPeriod: BlockNumber = 6 * BLOCKS_PER_HOUR; + pub const CorrectionPeriod: BlockNumber = BLOCKS_PER_DAY; // Authority pub const MaxAuthorities: u32 = 32; diff --git a/zrml/authorized/src/benchmarks.rs b/zrml/authorized/src/benchmarks.rs index 08db63f3a..c960d2ed7 100644 --- a/zrml/authorized/src/benchmarks.rs +++ b/zrml/authorized/src/benchmarks.rs @@ -37,9 +37,8 @@ use zeitgeist_primitives::{ use zrml_market_commons::MarketCommonsPalletApi; benchmarks! { - authorize_market_outcome { + authorize_market_outcome_first_report { let m in 1..63; - let d in 1..63; let origin = T::AuthorizedDisputeResolutionOrigin::successful_origin(); let market_id = 0u32.into(); @@ -50,22 +49,44 @@ benchmarks! { outcome: OutcomeReport::Scalar(1), }; + frame_system::Pallet::::set_block_number(42u32.into()); let now = frame_system::Pallet::::block_number(); - - let resolve_at = now.saturating_add(T::CorrectionPeriod::get() - 1u32.into()); - let report = AuthorityReport { resolve_at, outcome: OutcomeReport::Scalar(0) }; - for _ in 1..=m { - let id = T::MarketCommons::push_market(market_mock::()).unwrap(); - T::DisputeResolution::add_auto_resolve(&id, resolve_at).unwrap(); - } - AuthorizedOutcomeReports::::insert(market_id, report); - let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); - for _ in 1..=d { + for _ in 1..=m { let id = T::MarketCommons::push_market(market_mock::()).unwrap(); T::DisputeResolution::add_auto_resolve(&id, correction_period_ends_at).unwrap(); } - }: { call.dispatch_bypass_filter(origin)? } + }: { + call.dispatch_bypass_filter(origin)? + } verify { + let report = AuthorityReport { + resolve_at: correction_period_ends_at, + outcome: OutcomeReport::Scalar(1) + }; + assert_eq!(AuthorizedOutcomeReports::::get(market_id).unwrap(), report); + } + + authorize_market_outcome_existing_report { + let origin = T::AuthorizedDisputeResolutionOrigin::successful_origin(); + let market_id = 0u32.into(); + let market = market_mock::(); + T::MarketCommons::push_market(market).unwrap(); + let call = Call::::authorize_market_outcome { + market_id, + outcome: OutcomeReport::Scalar(1), + }; + + frame_system::Pallet::::set_block_number(42u32.into()); + let now = frame_system::Pallet::::block_number(); + let resolve_at = now.saturating_add(T::CorrectionPeriod::get() - 1u32.into()); + let report = AuthorityReport { resolve_at, outcome: OutcomeReport::Scalar(0) }; + AuthorizedOutcomeReports::::insert(market_id, report); + }: { + call.dispatch_bypass_filter(origin)? + } verify { + let report = AuthorityReport { resolve_at, outcome: OutcomeReport::Scalar(1) }; + assert_eq!(AuthorizedOutcomeReports::::get(market_id).unwrap(), report); + } } impl_benchmark_test_suite!( diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 03f52b7a3..279bc9aa5 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -76,10 +76,11 @@ mod pallet { impl Pallet { /// Overwrites already provided outcomes for the same market and account. #[frame_support::transactional] - #[pallet::weight(T::WeightInfo::authorize_market_outcome( - CacheSize::get(), - CacheSize::get(), - ))] + #[pallet::weight( + T::WeightInfo::authorize_market_outcome_first_report(CacheSize::get()).max( + T::WeightInfo::authorize_market_outcome_existing_report(), + ) + )] pub fn authorize_market_outcome( origin: OriginFor, market_id: MarketIdOf, @@ -94,16 +95,27 @@ mod pallet { Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - let ids_len_1 = Self::remove_auto_resolve(&market_id); - let now = frame_system::Pallet::::block_number(); - let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); - let ids_len_2 = - T::DisputeResolution::add_auto_resolve(&market_id, correction_period_ends_at)?; + let mut ids_len: Option = None; + let report = match AuthorizedOutcomeReports::::get(market_id) { + Some(report) => AuthorityReport { resolve_at: report.resolve_at, outcome }, + None => { + let now = frame_system::Pallet::::block_number(); + let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); + ids_len = Some(T::DisputeResolution::add_auto_resolve( + &market_id, + correction_period_ends_at, + )?); + AuthorityReport { resolve_at: correction_period_ends_at, outcome } + } + }; - let report = AuthorityReport { resolve_at: correction_period_ends_at, outcome }; AuthorizedOutcomeReports::::insert(market_id, report); - Ok(Some(T::WeightInfo::authorize_market_outcome(ids_len_1, ids_len_2)).into()) + if let Some(len) = ids_len { + Ok(Some(T::WeightInfo::authorize_market_outcome_first_report(len)).into()) + } else { + Ok(Some(T::WeightInfo::authorize_market_outcome_existing_report()).into()) + } } } @@ -174,16 +186,6 @@ mod pallet { fn get_auto_resolve(market_id: &MarketIdOf) -> Option { AuthorizedOutcomeReports::::get(market_id).map(|report| report.resolve_at) } - - /// Return the number of elements from the vector implied by the `remove_auto_resolve` call. - /// This is especially useful to calculate a proper weight. - fn remove_auto_resolve(market_id: &MarketIdOf) -> u32 { - if let Some(resolve_at) = Self::get_auto_resolve(market_id) { - T::DisputeResolution::remove_auto_resolve(market_id, resolve_at) - } else { - 0u32 - } - } } impl DisputeApi for Pallet diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index 0808e2d6b..ea3de11fb 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -49,7 +49,7 @@ fn authorize_market_outcome_inserts_a_new_outcome() { } #[test] -fn authorize_market_outcome_resets_dispute_resolution() { +fn authorize_market_outcome_does_not_reset_dispute_resolution() { ExtBuilder::default().build().execute_with(|| { Markets::::insert(0, market_mock::()); @@ -67,18 +67,18 @@ fn authorize_market_outcome_resets_dispute_resolution() { assert_eq!(mock_storage::MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![0]); - frame_system::Pallet::::set_block_number(resolve_at_0 - 1); - let now = frame_system::Pallet::::block_number(); - let resolve_at_1 = now + ::CorrectionPeriod::get(); - assert_ok!(Authorized::authorize_market_outcome( Origin::signed(AuthorizedDisputeResolutionUser::get()), 0, OutcomeReport::Scalar(2) )); - assert_eq!(mock_storage::MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![]); - assert_eq!(mock_storage::MarketIdsPerDisputeBlock::::get(resolve_at_1), vec![0]); + assert_eq!( + AuthorizedOutcomeReports::::get(0).unwrap(), + AuthorityReport { outcome: OutcomeReport::Scalar(2), resolve_at: resolve_at_0 } + ); + + assert_eq!(mock_storage::MarketIdsPerDisputeBlock::::get(resolve_at_0), vec![0]); }); } diff --git a/zrml/authorized/src/weights.rs b/zrml/authorized/src/weights.rs index 000326fe4..f1cb2d6a0 100644 --- a/zrml/authorized/src/weights.rs +++ b/zrml/authorized/src/weights.rs @@ -18,8 +18,8 @@ //! Autogenerated weights for zrml_authorized //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-12-05, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! DATE: 2023-01-04, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Native), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: // ./target/release/zeitgeist @@ -30,7 +30,7 @@ // --repeat=1000 // --pallet=zrml_authorized // --extrinsic=* -// --execution=wasm +// --execution=Native // --wasm-execution=compiled // --heap-pages=4096 // --output=./zrml/authorized/src/weights.rs @@ -45,7 +45,8 @@ use frame_support::{traits::Get, weights::Weight}; /// Trait containing the required functions for weight retrival within /// zrml_authorized (automatically generated) pub trait WeightInfoZeitgeist { - fn authorize_market_outcome(m: u32, d: u32) -> Weight; + fn authorize_market_outcome_first_report(m: u32) -> Weight; + fn authorize_market_outcome_existing_report() -> Weight; } /// Weight functions for zrml_authorized (automatically generated) @@ -53,14 +54,19 @@ pub struct WeightInfo(PhantomData); impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons Markets (r:1 w:0) // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) - // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:2 w:2) - fn authorize_market_outcome(m: u32, d: u32) -> Weight { - (22_684_000 as Weight) + // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) + fn authorize_market_outcome_first_report(m: u32) -> Weight { + (17_077_000 as Weight) // Standard Error: 0 - .saturating_add((26_000 as Weight).saturating_mul(m as Weight)) - // Standard Error: 0 - .saturating_add((13_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) + .saturating_add((52_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) + } + // Storage: MarketCommons Markets (r:1 w:0) + // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) + fn authorize_market_outcome_existing_report() -> Weight { + (12_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } } From bce0c39d5265c80c5bc9154e739974a00f6fa740 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Wed, 4 Jan 2023 14:57:29 +0100 Subject: [PATCH 81/93] add description for the changes made --- docs/changelog_for_devs.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/changelog_for_devs.md b/docs/changelog_for_devs.md index 9f113d413..fd1a46217 100644 --- a/docs/changelog_for_devs.md +++ b/docs/changelog_for_devs.md @@ -5,6 +5,14 @@ which has three fields: `who` (the account that reserved the bond), `value` (the amount reserved), `is_settled` (a flag which determines if the bond was already unreserved and/or (partially) slashed). +- The market dispute mechanisms are now able to control their resolution. The + `CorrectionPeriod` parameter determines how long the authorized pallet can + call `authorize_market_outcome` again after the first call to it (fat-finger + protection). The authority report now includes its resolution block number. + This is the time of the first call to `authorize_market_outcome` plus the + `CorrectionPeriod`. Added new dispatchable call: + - `resolve_failed_mdm` - In case an MDM can fail, this extrinsic handles the + resolution of the market. # v0.3.7 From ceddfa944e675656035e025b0e7ff3aed0e642fe Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 5 Jan 2023 05:46:55 +0100 Subject: [PATCH 82/93] remove resolve_failed_mdm --- docs/changelog_for_devs.md | 4 +- zrml/prediction-markets/src/benchmarks.rs | 64 ------------------ zrml/prediction-markets/src/lib.rs | 54 --------------- zrml/prediction-markets/src/tests.rs | 81 ----------------------- zrml/prediction-markets/src/weights.rs | 25 ------- 5 files changed, 1 insertion(+), 227 deletions(-) diff --git a/docs/changelog_for_devs.md b/docs/changelog_for_devs.md index fd1a46217..fde20e06c 100644 --- a/docs/changelog_for_devs.md +++ b/docs/changelog_for_devs.md @@ -10,9 +10,7 @@ call `authorize_market_outcome` again after the first call to it (fat-finger protection). The authority report now includes its resolution block number. This is the time of the first call to `authorize_market_outcome` plus the - `CorrectionPeriod`. Added new dispatchable call: - - `resolve_failed_mdm` - In case an MDM can fail, this extrinsic handles the - resolution of the market. + `CorrectionPeriod`. # v0.3.7 diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 1127e4c11..75ee4169b 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -864,70 +864,6 @@ benchmarks! { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } - resolve_expired_mdm_authorized_scalar { - let report_outcome = OutcomeReport::Scalar(u128::MAX); - let (caller, market_id) = create_close_and_report_market::( - MarketCreation::Permissionless, - MarketType::Scalar(0u128..=u128::MAX), - report_outcome, - )?; - - >::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; - Ok(()) - })?; - - let market = >::market(&market_id)?; - if let MarketType::Scalar(range) = market.market_type { - assert!(1u128 < *range.end()); - } else { - panic!("Must create scalar market"); - } - - // authorize mdm allows only one dispute - let outcome = OutcomeReport::Scalar(1u128); - let disputor = account("disputor", 0, 0); - T::AssetManager::deposit(Asset::Ztg, &disputor, (u128::MAX).saturated_into())?; - Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; - - let call = Call::::resolve_failed_mdm { market_id }; - }: { - call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; - } verify { - assert_last_event::(Event::FailedDisputeMechanismResolved::(market_id).into()); - } - - resolve_expired_mdm_authorized_categorical { - let categories = T::MaxCategories::get(); - let (caller, market_id) = - setup_reported_categorical_market_with_pool::( - categories.into(), - OutcomeReport::Categorical(0u16) - )?; - - >::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::Authorized; - Ok(()) - })?; - - // authorize mdm allows only one dispute - let outcome = OutcomeReport::Categorical(1u16); - let disputor = account("disputor", 0, 0); - let dispute_bond = crate::pallet::default_dispute_bond::(0_usize); - T::AssetManager::deposit( - Asset::Ztg, - &disputor, - dispute_bond, - )?; - Pallet::::dispute(RawOrigin::Signed(disputor).into(), market_id, outcome)?; - - let call = Call::::resolve_failed_mdm { market_id }; - }: { - call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; - } verify { - assert_last_event::(Event::FailedDisputeMechanismResolved::(market_id).into()); - } - handle_expired_advised_market { let (_, market_id) = create_market_common::( MarketCreation::Advised, diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 452b7a3a5..d8132fc80 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -575,60 +575,6 @@ mod pallet { Ok((Some(T::WeightInfo::dispute_authorized())).into()) } - /// Resolve the market, - /// if the dispute mechanism was unable to come to a conclusion in a specified time. - /// - /// # Weight - /// - /// Complexity: `O(n)`, where `n` is the number of outstanding disputes. - #[pallet::weight( - T::WeightInfo::resolve_expired_mdm_authorized_categorical() - .max(T::WeightInfo::resolve_expired_mdm_authorized_scalar()) - )] - #[transactional] - pub fn resolve_failed_mdm( - origin: OriginFor, - #[pallet::compact] market_id: MarketIdOf, - ) -> DispatchResultWithPostInfo { - ensure_signed(origin)?; - let market = >::market(&market_id)?; - ensure!(market.status == MarketStatus::Disputed, Error::::InvalidMarketStatus); - - let disputes = Disputes::::get(market_id); - - // TODO(#782): use multiple benchmarks paths for different dispute mechanisms - let _has_failed = match market.dispute_mechanism { - MarketDisputeMechanism::Authorized => { - T::Authorized::has_failed(&disputes, &market_id, &market)? - } - MarketDisputeMechanism::Court => { - T::Court::has_failed(&disputes, &market_id, &market)? - } - MarketDisputeMechanism::SimpleDisputes => { - T::SimpleDisputes::has_failed(&disputes, &market_id, &market)? - } - }; - - // TODO (#918): benchmarks only reach the end when a dispute mechanism has failed - #[cfg(feature = "runtime-benchmarks")] - let _has_failed = true; - - ensure!(_has_failed, Error::::DisputeMechanismHasNotFailed); - - Self::on_resolution(&market_id, &market)?; - - Self::deposit_event(Event::FailedDisputeMechanismResolved(market_id)); - - let weight = match market.market_type { - MarketType::Scalar(_) => T::WeightInfo::resolve_expired_mdm_authorized_scalar(), - MarketType::Categorical(_) => { - T::WeightInfo::resolve_expired_mdm_authorized_categorical() - } - }; - - Ok((Some(weight)).into()) - } - /// Create a permissionless market, buy complete sets and deploy a pool with specified /// liquidity. /// diff --git a/zrml/prediction-markets/src/tests.rs b/zrml/prediction-markets/src/tests.rs index 3e680f851..8e9cb2bae 100644 --- a/zrml/prediction-markets/src/tests.rs +++ b/zrml/prediction-markets/src/tests.rs @@ -3081,87 +3081,6 @@ fn authorized_correctly_resolves_disputed_market() { }); } -/* -TODO (#918): when we later allow a simple account id to be the authority, this expiration limit for the authority becomes useful - -#[test] -fn on_resolution_defaults_to_oracle_report_in_case_of_failed_authorized_mdm() { - ExtBuilder::default().build().execute_with(|| { - assert!(Balances::free_balance(Treasury::account_id()).is_zero()); - let end = 2; - let market_id = 0; - assert_ok!(PredictionMarkets::create_market( - Origin::signed(ALICE), - BOB, - MarketPeriod::Block(0..end), - get_deadlines(), - gen_metadata(2), - MarketCreation::Permissionless, - MarketType::Categorical(::MinCategories::get()), - MarketDisputeMechanism::Authorized, - ScoringRule::CPMM, - )); - assert_ok!(PredictionMarkets::buy_complete_set(Origin::signed(CHARLIE), market_id, CENT)); - - let market = MarketCommons::market(&0).unwrap(); - let grace_period = end + market.deadlines.grace_period; - run_to_block(grace_period + 1); - assert_ok!(PredictionMarkets::report( - Origin::signed(BOB), - market_id, - OutcomeReport::Categorical(1) - )); - let dispute_at = end + grace_period + 2; - run_to_block(dispute_at); - assert_ok!(PredictionMarkets::dispute( - Origin::signed(CHARLIE), - market_id, - OutcomeReport::Categorical(0) - )); - let market = MarketCommons::market(&market_id).unwrap(); - assert_eq!(market.status, MarketStatus::Disputed); - - let disputes = crate::Disputes::::get(0); - assert_eq!(disputes.len(), 1); - - let charlie_reserved = Balances::reserved_balance(&CHARLIE); - assert_eq!(charlie_reserved, DisputeBond::get()); - - run_blocks(::ReportPeriod::get()); - assert_noop!( - PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id), - Error::::DisputeMechanismHasNotFailed - ); - - run_blocks(1); - // ReportPeriod is now over - assert_ok!(PredictionMarkets::resolve_failed_mdm(Origin::signed(FRED), market_id)); - - let market_after = MarketCommons::market(&market_id).unwrap(); - assert_eq!(market_after.status, MarketStatus::Resolved); - let disputes = crate::Disputes::::get(0); - assert_eq!(disputes.len(), 0); - assert_ok!(PredictionMarkets::redeem_shares(Origin::signed(CHARLIE), market_id)); - - // Make sure rewards are right: - // - // - Bob reported "correctly" and in time, so Alice and Bob don't get slashed - // - Charlie started a dispute which was abandoned, hence he's slashed and his rewards are - // moved to the treasury - let alice_balance = Balances::free_balance(&ALICE); - assert_eq!(alice_balance, 1_000 * BASE); - let bob_balance = Balances::free_balance(&BOB); - assert_eq!(bob_balance, 1_000 * BASE); - let charlie_balance = Balances::free_balance(&CHARLIE); - assert_eq!(charlie_balance, 1_000 * BASE - charlie_reserved); - assert_eq!(Balances::free_balance(Treasury::account_id()), charlie_reserved); - - assert!(market_after.bonds.creation.unwrap().is_settled); - assert!(market_after.bonds.oracle.unwrap().is_settled); - }); -} -*/ - #[test] fn approve_market_correctly_unreserves_advisory_bond() { ExtBuilder::default().build().execute_with(|| { diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index 78ef6a90f..de6f9dfc8 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -61,8 +61,6 @@ pub trait WeightInfoZeitgeist { fn deploy_swap_pool_for_market_open_pool(a: u32) -> Weight; fn start_global_dispute(m: u32, n: u32) -> Weight; fn dispute_authorized() -> Weight; - fn resolve_expired_mdm_authorized_scalar() -> Weight; - fn resolve_expired_mdm_authorized_categorical() -> Weight; fn handle_expired_advised_market() -> Weight; fn internal_resolve_categorical_reported() -> Weight; fn internal_resolve_categorical_disputed(d: u32) -> Weight; @@ -309,29 +307,6 @@ impl WeightInfoZeitgeist for WeightInfo { .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - // Storage: MarketCommons Markets (r:1 w:1) - // Storage: PredictionMarkets Disputes (r:1 w:1) - // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) - // Storage: Balances Reserves (r:2 w:2) - // Storage: System Account (r:2 w:2) - // Storage: MarketCommons MarketPool (r:1 w:0) - fn resolve_expired_mdm_authorized_scalar() -> Weight { - (105_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(8 as Weight)) - .saturating_add(T::DbWeight::get().writes(6 as Weight)) - } - // Storage: MarketCommons Markets (r:1 w:1) - // Storage: PredictionMarkets Disputes (r:1 w:1) - // Storage: Authorized AuthorizedOutcomeReports (r:1 w:0) - // Storage: Balances Reserves (r:2 w:2) - // Storage: System Account (r:2 w:2) - // Storage: MarketCommons MarketPool (r:1 w:0) - // Storage: Swaps Pools (r:1 w:1) - fn resolve_expired_mdm_authorized_categorical() -> Weight { - (135_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(9 as Weight)) - .saturating_add(T::DbWeight::get().writes(7 as Weight)) - } // Storage: Balances Reserves (r:1 w:1) // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets MarketIdsForEdit (r:0 w:1) From 29a684da5f9d21f1185970e3968363781c8fb2e8 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 5 Jan 2023 05:52:42 +0100 Subject: [PATCH 83/93] use ord_parameter_types macro --- zrml/authorized/src/mock.rs | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 966f417c6..0fe3dfa7a 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -23,7 +23,7 @@ use crate::{self as zrml_authorized, mock_storage::pallet as mock_storage}; use alloc::{vec, vec::Vec}; use frame_support::{ construct_runtime, ord_parameter_types, - pallet_prelude::{DispatchError, Get, Weight}, + pallet_prelude::{DispatchError, Weight}, traits::Everything, BoundedVec, }; @@ -67,17 +67,9 @@ construct_runtime!( ord_parameter_types! { pub const AuthorizedDisputeResolutionUser: AccountIdTest = ALICE; + pub const MaxDisputes: u32 = 64; } -pub struct MaxDisputes; -impl Get for MaxDisputes { - fn get() -> u32 { - 64u32 - } -} - -type MaxDisputesTest = MaxDisputes; - // MockResolution implements DisputeResolutionApi with no-ops. pub struct MockResolution; @@ -86,7 +78,7 @@ impl DisputeResolutionApi for MockResolution { type Balance = Balance; type BlockNumber = BlockNumber; type MarketId = MarketId; - type MaxDisputes = MaxDisputesTest; + type MaxDisputes = MaxDisputes; type Moment = Moment; fn resolve( From 7a6eaad7110b2208addd96a534a3692817df3778 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Thu, 5 Jan 2023 07:20:49 +0100 Subject: [PATCH 84/93] check auto resolve in case of existing report --- primitives/src/traits/dispute_api.rs | 7 +++++ zrml/authorized/src/benchmarks.rs | 8 +++++ zrml/authorized/src/lib.rs | 44 +++++++++++++++++++--------- zrml/authorized/src/mock.rs | 4 +++ zrml/authorized/src/weights.rs | 23 ++++++++------- zrml/court/src/mock.rs | 4 +++ zrml/prediction-markets/src/lib.rs | 4 +++ zrml/simple-disputes/src/mock.rs | 4 +++ 8 files changed, 74 insertions(+), 24 deletions(-) diff --git a/primitives/src/traits/dispute_api.rs b/primitives/src/traits/dispute_api.rs index c49693b8d..17d062692 100644 --- a/primitives/src/traits/dispute_api.rs +++ b/primitives/src/traits/dispute_api.rs @@ -121,6 +121,13 @@ pub trait DisputeResolutionApi { resolve_at: Self::BlockNumber, ) -> Result; + /// Check if a future block resolution of a disputed market exists. + /// + /// # Returns + /// + /// Returns `true` if the future block resolution exists, otherwise `false`. + fn auto_resolve_exists(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> bool; + /// Remove a future block resolution of a disputed market. /// /// # Returns diff --git a/zrml/authorized/src/benchmarks.rs b/zrml/authorized/src/benchmarks.rs index c960d2ed7..4203bb42e 100644 --- a/zrml/authorized/src/benchmarks.rs +++ b/zrml/authorized/src/benchmarks.rs @@ -67,6 +67,8 @@ benchmarks! { } authorize_market_outcome_existing_report { + let m in 1..63; + let origin = T::AuthorizedDisputeResolutionOrigin::successful_origin(); let market_id = 0u32.into(); let market = market_mock::(); @@ -79,6 +81,12 @@ benchmarks! { frame_system::Pallet::::set_block_number(42u32.into()); let now = frame_system::Pallet::::block_number(); let resolve_at = now.saturating_add(T::CorrectionPeriod::get() - 1u32.into()); + + for _ in 1..=m { + let id = T::MarketCommons::push_market(market_mock::()).unwrap(); + T::DisputeResolution::add_auto_resolve(&id, resolve_at).unwrap(); + } + let report = AuthorityReport { resolve_at, outcome: OutcomeReport::Scalar(0) }; AuthorizedOutcomeReports::::insert(market_id, report); }: { diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 279bc9aa5..18b088794 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -78,7 +78,7 @@ mod pallet { #[frame_support::transactional] #[pallet::weight( T::WeightInfo::authorize_market_outcome_first_report(CacheSize::get()).max( - T::WeightInfo::authorize_market_outcome_existing_report(), + T::WeightInfo::authorize_market_outcome_existing_report(CacheSize::get()), ) )] pub fn authorize_market_outcome( @@ -95,26 +95,42 @@ mod pallet { Error::::MarketDoesNotHaveDisputeMechanismAuthorized ); - let mut ids_len: Option = None; - let report = match AuthorizedOutcomeReports::::get(market_id) { - Some(report) => AuthorityReport { resolve_at: report.resolve_at, outcome }, + let now = frame_system::Pallet::::block_number(); + + let add_resolve_at = |resolve_at| -> Result { + let ids_len = T::DisputeResolution::add_auto_resolve(&market_id, resolve_at)?; + Ok(ids_len) + }; + + let report_opt = AuthorizedOutcomeReports::::get(market_id); + let (report, ids_len) = match &report_opt { + Some(report) => { + let mut resolve_at = report.resolve_at; + let exists = T::DisputeResolution::auto_resolve_exists(&market_id, resolve_at); + let mut ids_len = 0u32; + if resolve_at < now { + // resolve_at is in the past, but should have already been resolved + resolve_at = now.saturating_add(T::CorrectionPeriod::get()); + ids_len = add_resolve_at(resolve_at)?; + } else if !exists { + ids_len = add_resolve_at(resolve_at)?; + } + + (AuthorityReport { resolve_at, outcome }, ids_len) + } None => { - let now = frame_system::Pallet::::block_number(); - let correction_period_ends_at = now.saturating_add(T::CorrectionPeriod::get()); - ids_len = Some(T::DisputeResolution::add_auto_resolve( - &market_id, - correction_period_ends_at, - )?); - AuthorityReport { resolve_at: correction_period_ends_at, outcome } + let resolve_at = now.saturating_add(T::CorrectionPeriod::get()); + let ids_len = add_resolve_at(resolve_at)?; + (AuthorityReport { resolve_at, outcome }, ids_len) } }; AuthorizedOutcomeReports::::insert(market_id, report); - if let Some(len) = ids_len { - Ok(Some(T::WeightInfo::authorize_market_outcome_first_report(len)).into()) + if report_opt.is_none() { + Ok(Some(T::WeightInfo::authorize_market_outcome_first_report(ids_len)).into()) } else { - Ok(Some(T::WeightInfo::authorize_market_outcome_existing_report()).into()) + Ok(Some(T::WeightInfo::authorize_market_outcome_existing_report(ids_len)).into()) } } } diff --git a/zrml/authorized/src/mock.rs b/zrml/authorized/src/mock.rs index 0fe3dfa7a..056e59f1e 100644 --- a/zrml/authorized/src/mock.rs +++ b/zrml/authorized/src/mock.rs @@ -102,6 +102,10 @@ impl DisputeResolutionApi for MockResolution { Ok(ids_len) } + fn auto_resolve_exists(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> bool { + >::get(resolve_at).contains(market_id) + } + fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32 { >::mutate(resolve_at, |ids| -> u32 { ids.retain(|id| id != market_id); diff --git a/zrml/authorized/src/weights.rs b/zrml/authorized/src/weights.rs index f1cb2d6a0..d668250bb 100644 --- a/zrml/authorized/src/weights.rs +++ b/zrml/authorized/src/weights.rs @@ -18,8 +18,8 @@ //! Autogenerated weights for zrml_authorized //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-01-04, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` -//! EXECUTION: Some(Native), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 +//! DATE: 2023-01-05, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: // ./target/release/zeitgeist @@ -30,7 +30,7 @@ // --repeat=1000 // --pallet=zrml_authorized // --extrinsic=* -// --execution=Native +// --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 // --output=./zrml/authorized/src/weights.rs @@ -46,7 +46,7 @@ use frame_support::{traits::Get, weights::Weight}; /// zrml_authorized (automatically generated) pub trait WeightInfoZeitgeist { fn authorize_market_outcome_first_report(m: u32) -> Weight; - fn authorize_market_outcome_existing_report() -> Weight; + fn authorize_market_outcome_existing_report(m: u32) -> Weight; } /// Weight functions for zrml_authorized (automatically generated) @@ -56,17 +56,20 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) fn authorize_market_outcome_first_report(m: u32) -> Weight { - (17_077_000 as Weight) + (19_197_000 as Weight) // Standard Error: 0 - .saturating_add((52_000 as Weight).saturating_mul(m as Weight)) + .saturating_add((54_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: MarketCommons Markets (r:1 w:0) // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) - fn authorize_market_outcome_existing_report() -> Weight { - (12_000_000 as Weight) - .saturating_add(T::DbWeight::get().reads(2 as Weight)) - .saturating_add(T::DbWeight::get().writes(1 as Weight)) + // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) + fn authorize_market_outcome_existing_report(m: u32) -> Weight { + (21_694_000 as Weight) + // Standard Error: 0 + .saturating_add((63_000 as Weight).saturating_mul(m as Weight)) + .saturating_add(T::DbWeight::get().reads(3 as Weight)) + .saturating_add(T::DbWeight::get().writes(2 as Weight)) } } diff --git a/zrml/court/src/mock.rs b/zrml/court/src/mock.rs index 338defd91..11cfe03ee 100644 --- a/zrml/court/src/mock.rs +++ b/zrml/court/src/mock.rs @@ -91,6 +91,10 @@ impl DisputeResolutionApi for NoopResolution { Ok(0u32) } + fn auto_resolve_exists(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> bool { + false + } + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { 0u32 } diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index d8132fc80..a45398427 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -2919,6 +2919,10 @@ mod pallet { Ok(ids_len) } + fn auto_resolve_exists(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> bool { + >::get(resolve_at).contains(market_id) + } + fn remove_auto_resolve(market_id: &Self::MarketId, resolve_at: Self::BlockNumber) -> u32 { remove_auto_resolve::(market_id, resolve_at) } diff --git a/zrml/simple-disputes/src/mock.rs b/zrml/simple-disputes/src/mock.rs index f1ed7aa74..5e6afbcd6 100644 --- a/zrml/simple-disputes/src/mock.rs +++ b/zrml/simple-disputes/src/mock.rs @@ -79,6 +79,10 @@ impl DisputeResolutionApi for NoopResolution { Ok(0u32) } + fn auto_resolve_exists(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> bool { + false + } + fn remove_auto_resolve(_market_id: &Self::MarketId, _resolve_at: Self::BlockNumber) -> u32 { 0u32 } From c67a4a1ced20571bf78f5fe9022c8c9c9f72c58c Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 6 Jan 2023 15:35:03 +0100 Subject: [PATCH 85/93] handle market 432 --- zrml/authorized/src/benchmarks.rs | 31 +++++++++++---------- zrml/authorized/src/lib.rs | 26 +++--------------- zrml/authorized/src/weights.rs | 19 ++++++------- zrml/prediction-markets/src/migrations.rs | 33 ++++++++++++++++------- 4 files changed, 50 insertions(+), 59 deletions(-) diff --git a/zrml/authorized/src/benchmarks.rs b/zrml/authorized/src/benchmarks.rs index af4f52f23..b2f590903 100644 --- a/zrml/authorized/src/benchmarks.rs +++ b/zrml/authorized/src/benchmarks.rs @@ -44,10 +44,6 @@ benchmarks! { let market_id = 0u32.into(); let market = market_mock::(); T::MarketCommons::push_market(market).unwrap(); - let call = Call::::authorize_market_outcome { - market_id, - outcome: OutcomeReport::Scalar(1), - }; frame_system::Pallet::::set_block_number(42u32.into()); let now = frame_system::Pallet::::block_number(); @@ -56,6 +52,11 @@ benchmarks! { let id = T::MarketCommons::push_market(market_mock::()).unwrap(); T::DisputeResolution::add_auto_resolve(&id, correction_period_ends_at).unwrap(); } + + let call = Call::::authorize_market_outcome { + market_id, + outcome: OutcomeReport::Scalar(1), + }; }: { call.dispatch_bypass_filter(origin)? } verify { @@ -67,28 +68,26 @@ benchmarks! { } authorize_market_outcome_existing_report { - let m in 1..63; - let origin = T::AuthorizedDisputeResolutionOrigin::successful_origin(); let market_id = 0u32.into(); let market = market_mock::(); T::MarketCommons::push_market(market).unwrap(); - let call = Call::::authorize_market_outcome { - market_id, - outcome: OutcomeReport::Scalar(1), - }; frame_system::Pallet::::set_block_number(42u32.into()); - let now = frame_system::Pallet::::block_number(); - let resolve_at = now.saturating_add(T::CorrectionPeriod::get() - 1u32.into()); - for _ in 1..=m { - let id = T::MarketCommons::push_market(market_mock::()).unwrap(); - T::DisputeResolution::add_auto_resolve(&id, resolve_at).unwrap(); - } + let now = frame_system::Pallet::::block_number(); + let resolve_at = now.saturating_add(T::CorrectionPeriod::get()); let report = AuthorityReport { resolve_at, outcome: OutcomeReport::Scalar(0) }; AuthorizedOutcomeReports::::insert(market_id, report); + + let now = frame_system::Pallet::::block_number(); + frame_system::Pallet::::set_block_number(now + 42u32.into()); + + let call = Call::::authorize_market_outcome { + market_id, + outcome: OutcomeReport::Scalar(1), + }; }: { call.dispatch_bypass_filter(origin)? } verify { diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index 3c9903ad5..bb7361ebd 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -78,7 +78,7 @@ mod pallet { #[frame_support::transactional] #[pallet::weight( T::WeightInfo::authorize_market_outcome_first_report(CacheSize::get()).max( - T::WeightInfo::authorize_market_outcome_existing_report(CacheSize::get()), + T::WeightInfo::authorize_market_outcome_existing_report(), ) )] pub fn authorize_market_outcome( @@ -97,30 +97,12 @@ mod pallet { let now = frame_system::Pallet::::block_number(); - let add_resolve_at = |resolve_at| -> Result { - let ids_len = T::DisputeResolution::add_auto_resolve(&market_id, resolve_at)?; - Ok(ids_len) - }; - let report_opt = AuthorizedOutcomeReports::::get(market_id); let (report, ids_len) = match &report_opt { - Some(report) => { - let mut resolve_at = report.resolve_at; - let exists = T::DisputeResolution::auto_resolve_exists(&market_id, resolve_at); - let mut ids_len = 0u32; - if resolve_at < now { - // resolve_at is in the past, but should have already been resolved - resolve_at = now.saturating_add(T::CorrectionPeriod::get()); - ids_len = add_resolve_at(resolve_at)?; - } else if !exists { - ids_len = add_resolve_at(resolve_at)?; - } - - (AuthorityReport { resolve_at, outcome }, ids_len) - } + Some(report) => (AuthorityReport { resolve_at: report.resolve_at, outcome }, 0u32), None => { let resolve_at = now.saturating_add(T::CorrectionPeriod::get()); - let ids_len = add_resolve_at(resolve_at)?; + let ids_len = T::DisputeResolution::add_auto_resolve(&market_id, resolve_at)?; (AuthorityReport { resolve_at, outcome }, ids_len) } }; @@ -130,7 +112,7 @@ mod pallet { if report_opt.is_none() { Ok(Some(T::WeightInfo::authorize_market_outcome_first_report(ids_len)).into()) } else { - Ok(Some(T::WeightInfo::authorize_market_outcome_existing_report(ids_len)).into()) + Ok(Some(T::WeightInfo::authorize_market_outcome_existing_report()).into()) } } } diff --git a/zrml/authorized/src/weights.rs b/zrml/authorized/src/weights.rs index d668250bb..b2cb712bd 100644 --- a/zrml/authorized/src/weights.rs +++ b/zrml/authorized/src/weights.rs @@ -18,7 +18,7 @@ //! Autogenerated weights for zrml_authorized //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2023-01-05, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-01-06, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: @@ -46,7 +46,7 @@ use frame_support::{traits::Get, weights::Weight}; /// zrml_authorized (automatically generated) pub trait WeightInfoZeitgeist { fn authorize_market_outcome_first_report(m: u32) -> Weight; - fn authorize_market_outcome_existing_report(m: u32) -> Weight; + fn authorize_market_outcome_existing_report() -> Weight; } /// Weight functions for zrml_authorized (automatically generated) @@ -56,20 +56,17 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) fn authorize_market_outcome_first_report(m: u32) -> Weight { - (19_197_000 as Weight) + (31_031_000 as Weight) // Standard Error: 0 - .saturating_add((54_000 as Weight).saturating_mul(m as Weight)) + .saturating_add((85_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: MarketCommons Markets (r:1 w:0) // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) - // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) - fn authorize_market_outcome_existing_report(m: u32) -> Weight { - (21_694_000 as Weight) - // Standard Error: 0 - .saturating_add((63_000 as Weight).saturating_mul(m as Weight)) - .saturating_add(T::DbWeight::get().reads(3 as Weight)) - .saturating_add(T::DbWeight::get().writes(2 as Weight)) + fn authorize_market_outcome_existing_report() -> Weight { + (24_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(2 as Weight)) + .saturating_add(T::DbWeight::get().writes(1 as Weight)) } } diff --git a/zrml/prediction-markets/src/migrations.rs b/zrml/prediction-markets/src/migrations.rs index b897cdadc..618ebcf94 100644 --- a/zrml/prediction-markets/src/migrations.rs +++ b/zrml/prediction-markets/src/migrations.rs @@ -424,7 +424,7 @@ mod tests { use alloc::string::ToString; use frame_support::{migration::storage_key_iter, Twox64Concat}; use frame_system::pallet_prelude::BlockNumberFor; -use sp_runtime::traits::Zero; +use sp_runtime::traits::Saturating; use zeitgeist_primitives::types::AuthorityReport; use zrml_authorized::Pallet as AuthorizedPallet; @@ -477,6 +477,9 @@ impl OnRuntim AuthorityReport>, )> = Vec::new(); + let now = frame_system::Pallet::::block_number(); + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + for (market_id, old_value) in storage_key_iter::< ::MarketId, OutcomeReport, @@ -489,13 +492,13 @@ impl OnRuntim authorized_resolutions.get(&market_id).cloned(); match resolve_at { - Some(block) => { + Some(block) if now <= block => { new_storage_map.push(( market_id, AuthorityReport { resolve_at: block, outcome: old_value }, )); } - None => { + _ => { log::warn!( "AddFieldToAuthorityReport: Market was not found in \ MarketIdsPerDisputeBlock; market id: {:?}", @@ -504,13 +507,23 @@ impl OnRuntim // example case market id 432 // https://github.com/zeitgeistpm/zeitgeist/pull/701 market id 432 is invalid, because of zero-division error in the past // we have to handle manually here, because MarketIdsPerDisputeBlock does not contain 432 - new_storage_map.push(( - market_id, - AuthorityReport { - resolve_at: >::zero(), - outcome: old_value, - }, - )); + let mut resolve_at = now.saturating_add(T::CorrectionPeriod::get()); + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + + let mut bounded_vec = >::get(resolve_at); + while bounded_vec.is_full() { + // roll the dice until we find a block that is not full + total_weight = total_weight.saturating_add(T::DbWeight::get().reads(1)); + resolve_at = resolve_at.saturating_add(1u32.into()); + bounded_vec = >::get(resolve_at); + } + // is not full, so we can push + bounded_vec.force_push(market_id); + >::insert(resolve_at, bounded_vec); + total_weight = total_weight.saturating_add(T::DbWeight::get().writes(1)); + + new_storage_map + .push((market_id, AuthorityReport { resolve_at, outcome: old_value })); } } } From 8c79cf676f07f5efd42d8065741c355ecc7847bc Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 6 Jan 2023 16:04:44 +0100 Subject: [PATCH 86/93] correct pm disputes authorized benchmarks --- zrml/prediction-markets/src/benchmarks.rs | 129 ++++++++-------------- 1 file changed, 48 insertions(+), 81 deletions(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index ac4b05805..207502a7b 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -85,7 +85,7 @@ fn create_market_common( ) -> Result<(T::AccountId, MarketIdOf), &'static str> { pallet_timestamp::Pallet::::set_timestamp(0u32.into()); let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); let period = period.unwrap_or(MarketPeriod::Timestamp(range_start..range_end)); let (caller, oracle, deadlines, metadata, creation) = create_market_common_parameters::(permission)?; @@ -110,7 +110,7 @@ fn create_close_and_report_market( outcome: OutcomeReport, ) -> Result<(T::AccountId, MarketIdOf), &'static str> { let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); let period = MarketPeriod::Timestamp(range_start..range_end); let (caller, market_id) = create_market_common::(permission, options, ScoringRule::CPMM, Some(period))?; @@ -355,7 +355,7 @@ benchmarks! { let c in 0..63; let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, MarketType::Categorical(T::MaxCategories::get()), @@ -451,7 +451,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, @@ -460,28 +459,21 @@ benchmarks! { )?; >::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; + market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; let market = >::market(&market_id)?; - if let MarketType::Scalar(range) = market.market_type { - assert!((d as u128) < *range.end()); - } else { - panic!("Must create scalar market"); - } - for i in 0..d { - let outcome = OutcomeReport::Scalar((i % 2).into()); - let disputor = account("disputor", i + 1, 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 outcome = OutcomeReport::Scalar(0); + let disputor = account("disputor", 1, 0); + let dispute_bond = crate::pallet::default_dispute_bond::(0 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); // Authorize the outcome with the highest number of correct reporters to maximize the // number of transfers required (0 has (d+1)//2 reports, 1 has d//2 reports). @@ -505,7 +497,6 @@ benchmarks! { }: { call.dispatch_bypass_filter(close_origin)? } verify { - // simple disputes resolves to the last dispute outcome assert_last_event::(Event::MarketResolved::( market_id, MarketStatus::Resolved, @@ -515,7 +506,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) = @@ -525,21 +515,20 @@ benchmarks! { )?; >::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; + market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - for i in 0..d { - let outcome = OutcomeReport::Categorical((i % 2).saturated_into::()); - let disputor = account("disputor", i + 1, 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 outcome = OutcomeReport::Categorical(0u16); + let disputor = account("disputor", 1, 0); + let dispute_bond = crate::pallet::default_dispute_bond::(0 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); // Authorize the outcome with the highest number of correct reporters to maximize the // number of transfers required (0 has (d+1)//2 reports, 1 has d//2 reports). @@ -567,7 +556,7 @@ benchmarks! { assert_last_event::(Event::MarketResolved::( market_id, MarketStatus::Resolved, - OutcomeReport::Categorical((d % 2).saturated_into::()), + OutcomeReport::Categorical(0u16), ).into()); } @@ -644,7 +633,7 @@ benchmarks! { let dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; let scoring_rule = ScoringRule::CPMM; let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); let period = MarketPeriod::Timestamp(range_start..range_end); let (caller, oracle, deadlines, metadata, creation) = create_market_common_parameters::(MarketCreation::Advised)?; @@ -694,7 +683,7 @@ benchmarks! { let o in 0..63; let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, MarketType::Categorical(a.saturated_into()), @@ -750,7 +739,7 @@ benchmarks! { // We need to ensure, that period range start is now, // because we would like to open the pool now let range_start: MomentOf = >::now(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, MarketType::Categorical(a.saturated_into()), @@ -780,9 +769,7 @@ benchmarks! { }: { call.dispatch_bypass_filter(RawOrigin::Signed(caller).into())?; } verify { - let market_pool_id = >::market_pool( - &market_id.saturated_into() - )?; + let market_pool_id = >::market_pool(&market_id.saturated_into())?; let pool = T::Swaps::pool(market_pool_id)?; assert_eq!(pool.pool_status, PoolStatus::Active); } @@ -870,11 +857,6 @@ benchmarks! { })?; let market = >::market(&market_id)?; - if let MarketType::Scalar(range) = market.market_type { - assert!(1u128 < *range.end()); - } else { - panic!("Must create scalar market"); - } // only one dispute allowed for authorized mdm let dispute_outcome = OutcomeReport::Scalar(1u128); @@ -912,9 +894,6 @@ benchmarks! { } internal_resolve_categorical_disputed { - // d = num. disputes - let d in 1..T::MaxDisputes::get(); - let categories = T::MaxCategories::get(); let (caller, market_id) = setup_reported_categorical_market_with_pool::( @@ -922,18 +901,16 @@ benchmarks! { OutcomeReport::Categorical(1u16) )?; >::mutate_market(&market_id, |market| { - market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; + market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; - for i in 0..d { - let origin = caller.clone(); - Pallet::::dispute( - RawOrigin::Signed(origin).into(), - market_id, - OutcomeReport::Categorical((i % 2).saturated_into::()), - )?; - } + let origin = caller.clone(); + Pallet::::dispute( + RawOrigin::Signed(origin).into(), + market_id, + OutcomeReport::Categorical(0), + )?; // Authorize the outcome with the highest number of correct reporters to maximize the // number of transfers required (0 has (d+1)//2 reports, 1 has d//2 reports). AuthorizedPallet::::authorize_market_outcome( @@ -964,32 +941,22 @@ benchmarks! { } internal_resolve_scalar_disputed { - let d in 1..T::MaxDisputes::get(); - let (caller, market_id) = create_close_and_report_market::( MarketCreation::Permissionless, MarketType::Scalar(0u128..=u128::MAX), OutcomeReport::Scalar(u128::MAX), )?; >::mutate_market(&market_id, |market| { - // to allow multiple disputes use simple disputes - market.dispute_mechanism = MarketDisputeMechanism::SimpleDisputes; + market.dispute_mechanism = MarketDisputeMechanism::Authorized; Ok(()) })?; let market = >::market(&market_id)?; - if let MarketType::Scalar(range) = market.market_type { - assert!((d as u128) < *range.end()); - } else { - panic!("Must create scalar market"); - } - for i in 0..d { - let origin = caller.clone(); - Pallet::::dispute( - RawOrigin::Signed(origin).into(), - market_id, - OutcomeReport::Scalar((i % 2).into()) - )?; - } + let origin = caller.clone(); + Pallet::::dispute( + RawOrigin::Signed(origin).into(), + market_id, + OutcomeReport::Scalar(1) + )?; // Authorize the outcome with the highest number of correct reporters to maximize the // number of transfers required (0 has (d+1)//2 reports, 1 has d//2 reports). AuthorizedPallet::::authorize_market_outcome( @@ -1047,7 +1014,7 @@ benchmarks! { let r in 0..::MaxRejectReasonLen::get(); let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); let (_, market_id) = create_market_common::( MarketCreation::Advised, MarketType::Categorical(T::MaxCategories::get()), @@ -1079,7 +1046,7 @@ benchmarks! { // ensure range.start is now to get the heaviest path let range_start: MomentOf = >::now(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); let (caller, market_id) = create_market_common::( MarketCreation::Permissionless, MarketType::Categorical(T::MaxCategories::get()), @@ -1160,7 +1127,7 @@ benchmarks! { // ensure markets exist let start_block: T::BlockNumber = 100_000u64.saturated_into(); - let end_block: T::BlockNumber = 100_000_000u64.saturated_into(); + let end_block: T::BlockNumber = 1_000_000u64.saturated_into(); for _ in 0..31 { create_market_common::( MarketCreation::Permissionless, @@ -1171,7 +1138,7 @@ benchmarks! { } let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); for _ in 31..64 { create_market_common::( MarketCreation::Permissionless, @@ -1222,7 +1189,7 @@ benchmarks! { let d in 1..31; let range_start: MomentOf = 100_000u64.saturated_into(); - let range_end: MomentOf = 100_000_000u64.saturated_into(); + let range_end: MomentOf = 1_000_000u64.saturated_into(); // ensure markets exist for _ in 0..64 { let (_, market_id) = create_market_common::( From c46c579001cb63ccff9c0217ad49291244ed2b1d Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Fri, 6 Jan 2023 16:15:40 +0100 Subject: [PATCH 87/93] fix clippy --- zrml/prediction-markets/src/benchmarks.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/zrml/prediction-markets/src/benchmarks.rs b/zrml/prediction-markets/src/benchmarks.rs index 207502a7b..efac65a47 100644 --- a/zrml/prediction-markets/src/benchmarks.rs +++ b/zrml/prediction-markets/src/benchmarks.rs @@ -467,7 +467,7 @@ benchmarks! { let outcome = OutcomeReport::Scalar(0); let disputor = account("disputor", 1, 0); - let dispute_bond = crate::pallet::default_dispute_bond::(0 as usize); + let dispute_bond = crate::pallet::default_dispute_bond::(0_usize); T::AssetManager::deposit( Asset::Ztg, &disputor, @@ -521,7 +521,7 @@ benchmarks! { let outcome = OutcomeReport::Categorical(0u16); let disputor = account("disputor", 1, 0); - let dispute_bond = crate::pallet::default_dispute_bond::(0 as usize); + let dispute_bond = crate::pallet::default_dispute_bond::(0_usize); T::AssetManager::deposit( Asset::Ztg, &disputor, @@ -905,9 +905,8 @@ benchmarks! { Ok(()) })?; - let origin = caller.clone(); Pallet::::dispute( - RawOrigin::Signed(origin).into(), + RawOrigin::Signed(caller).into(), market_id, OutcomeReport::Categorical(0), )?; @@ -951,9 +950,8 @@ benchmarks! { Ok(()) })?; let market = >::market(&market_id)?; - let origin = caller.clone(); Pallet::::dispute( - RawOrigin::Signed(origin).into(), + RawOrigin::Signed(caller).into(), market_id, OutcomeReport::Scalar(1) )?; From aad23fce6af55dfd7005ea7fa9edd86eb95b533d Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Mon, 9 Jan 2023 10:10:50 +0100 Subject: [PATCH 88/93] update pm weights --- zrml/prediction-markets/src/lib.rs | 34 +--- zrml/prediction-markets/src/weights.rs | 250 ++++++++++++------------- 2 files changed, 132 insertions(+), 152 deletions(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index a45398427..ff1a15c12 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -346,15 +346,9 @@ mod pallet { .max( 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() - ) + T::WeightInfo::admin_move_market_to_resolved_scalar_disputed(CacheSize::get()) ).max( - T::WeightInfo::admin_move_market_to_resolved_categorical_disputed( - CacheSize::get(), - T::MaxDisputes::get() - ) + T::WeightInfo::admin_move_market_to_resolved_categorical_disputed(CacheSize::get()) ), Pays::No, ))] @@ -370,7 +364,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 = >::market(&market_id)?; let _ = Self::on_resolution(&market_id, &market)?; let weight = match market.market_type { @@ -379,10 +373,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()), }, @@ -391,10 +382,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()), }, @@ -2139,17 +2127,17 @@ mod pallet { time.saturated_into::().saturating_div(MILLISECS_PER_BLOCK.into()) } - fn calculate_internal_resolve_weight(market: &MarketOf, total_disputes: u32) -> Weight { + fn calculate_internal_resolve_weight(market: &MarketOf) -> Weight { if let MarketType::Categorical(_) = market.market_type { if let MarketStatus::Reported = market.status { T::WeightInfo::internal_resolve_categorical_reported() } else { - T::WeightInfo::internal_resolve_categorical_disputed(total_disputes) + T::WeightInfo::internal_resolve_categorical_disputed() } } else if let MarketStatus::Reported = market.status { T::WeightInfo::internal_resolve_scalar_reported() } else { - T::WeightInfo::internal_resolve_scalar_disputed(total_disputes) + T::WeightInfo::internal_resolve_scalar_disputed() } } @@ -2450,7 +2438,6 @@ mod pallet { } let mut total_weight = 0; - let disputes = Disputes::::get(market_id); let resolved_outcome = match market.status { MarketStatus::Reported => Self::resolve_reported_market(market_id, market)?, @@ -2476,10 +2463,7 @@ mod pallet { MarketStatus::Resolved, resolved_outcome, )); - Ok(total_weight.saturating_add(Self::calculate_internal_resolve_weight( - market, - disputes.len().saturated_into(), - ))) + Ok(total_weight.saturating_add(Self::calculate_internal_resolve_weight(market))) } pub(crate) fn process_subsidy_collecting_markets( diff --git a/zrml/prediction-markets/src/weights.rs b/zrml/prediction-markets/src/weights.rs index de6f9dfc8..496d959a4 100644 --- a/zrml/prediction-markets/src/weights.rs +++ b/zrml/prediction-markets/src/weights.rs @@ -18,11 +18,11 @@ //! Autogenerated weights for zrml_prediction_markets //! //! THIS FILE WAS AUTO-GENERATED USING THE SUBSTRATE BENCHMARK CLI VERSION 4.0.0-dev -//! DATE: 2022-11-25, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` +//! DATE: 2023-01-09, STEPS: `10`, REPEAT: 1000, LOW RANGE: `[]`, HIGH RANGE: `[]` //! EXECUTION: Some(Wasm), WASM-EXECUTION: Compiled, CHAIN: Some("dev"), DB CACHE: 1024 // Executed Command: -// ./target/production/zeitgeist +// ./target/release/zeitgeist // benchmark // pallet // --chain=dev @@ -33,8 +33,8 @@ // --execution=wasm // --wasm-execution=compiled // --heap-pages=4096 -// --template=./misc/weight_template.hbs // --output=./zrml/prediction-markets/src/weights.rs +// --template=./misc/weight_template.hbs #![allow(unused_parens)] #![allow(unused_imports)] @@ -50,8 +50,8 @@ pub trait WeightInfoZeitgeist { 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 request_edit(r: u32) -> Weight; fn buy_complete_set(a: u32) -> Weight; @@ -63,9 +63,9 @@ pub trait WeightInfoZeitgeist { fn dispute_authorized() -> Weight; fn handle_expired_advised_market() -> Weight; fn internal_resolve_categorical_reported() -> Weight; - fn internal_resolve_categorical_disputed(d: u32) -> Weight; + fn internal_resolve_categorical_disputed() -> Weight; fn internal_resolve_scalar_reported() -> Weight; - fn internal_resolve_scalar_disputed(d: u32) -> Weight; + fn internal_resolve_scalar_disputed() -> Weight; fn on_initialize_resolve_overhead() -> Weight; fn process_subsidy_collecting_markets_raw(a: u32) -> Weight; fn redeem_shares_categorical() -> Weight; @@ -91,12 +91,14 @@ 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 { - (207_687_000 as Weight) - // Standard Error: 53_000 - .saturating_add((22_986_000 as Weight).saturating_mul(a as Weight)) - // Standard Error: 52_000 - .saturating_add((276_000 as Weight).saturating_mul(r as Weight)) + fn admin_destroy_disputed_market(a: u32, d: u32, o: u32, _c: u32, _r: u32) -> Weight { + (131_391_000 as Weight) + // Standard Error: 3_000 + .saturating_add((22_410_000 as Weight).saturating_mul(a as Weight)) + // Standard Error: 56_000 + .saturating_add((1_219_000 as Weight).saturating_mul(d as Weight)) + // Standard Error: 3_000 + .saturating_add((66_000 as Weight).saturating_mul(o as Weight)) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(8 as Weight)) @@ -111,12 +113,10 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Tokens TotalIssuance (r:2 w:2) // Storage: PredictionMarkets MarketIdsPerReportBlock (r:1 w:1) // Storage: PredictionMarkets Disputes (r:0 w:1) - fn admin_destroy_reported_market(a: u32, _o: u32, c: u32, _r: u32) -> Weight { - (122_080_000 as Weight) - // Standard Error: 11_000 - .saturating_add((22_824_000 as Weight).saturating_mul(a as Weight)) - // Standard Error: 10_000 - .saturating_add((56_000 as Weight).saturating_mul(c as Weight)) + fn admin_destroy_reported_market(a: u32, _o: u32, _c: u32, _r: u32) -> Weight { + (148_923_000 as Weight) + // Standard Error: 4_000 + .saturating_add((22_300_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(8 as Weight)) @@ -127,11 +127,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerCloseTimeFrame (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) fn admin_move_market_to_closed(o: u32, c: u32) -> Weight { - (37_778_000 as Weight) - // Standard Error: 1_000 - .saturating_add((10_000 as Weight).saturating_mul(o as Weight)) - // Standard Error: 1_000 - .saturating_add((18_000 as Weight).saturating_mul(c as Weight)) + (38_298_000 as Weight) + // Standard Error: 0 + .saturating_add((21_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 0 + .saturating_add((7_000 as Weight).saturating_mul(c as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -141,9 +141,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) fn admin_move_market_to_resolved_scalar_reported(r: u32) -> Weight { - (65_196_000 as Weight) - // Standard Error: 2_000 - .saturating_add((35_000 as Weight).saturating_mul(r as Weight)) + (72_815_000 as Weight) + // Standard Error: 0 + .saturating_add((58_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -154,61 +154,55 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: Swaps Pools (r:1 w:1) fn admin_move_market_to_resolved_categorical_reported(r: u32) -> Weight { - (93_157_000 as Weight) - // Standard Error: 6_000 - .saturating_add((61_000 as Weight).saturating_mul(r as Weight)) + (101_641_000 as Weight) + // Standard Error: 1_000 + .saturating_add((57_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) + // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) - // Storage: Balances Reserves (r:7 w:7) - // Storage: System Account (r:6 w:6) + // Storage: Balances Reserves (r:2 w:2) + // Storage: GlobalDisputes Winners (r:1 w:0) + // Storage: System Account (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) - fn admin_move_market_to_resolved_scalar_disputed(r: u32, d: u32) -> Weight { - (79_803_000 as Weight) - // Standard Error: 4_000 - .saturating_add((34_000 as Weight).saturating_mul(r as Weight)) - // Standard Error: 63_000 - .saturating_add((21_525_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(d as Weight))) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) - .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(d as Weight))) + fn admin_move_market_to_resolved_scalar_disputed(r: u32) -> Weight { + (119_331_000 as Weight) + // Standard Error: 1_000 + .saturating_add((23_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(9 as Weight)) + .saturating_add(T::DbWeight::get().writes(7 as Weight)) } // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) + // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) - // Storage: Balances Reserves (r:7 w:7) - // Storage: System Account (r:6 w:6) + // Storage: Balances Reserves (r:2 w:2) + // Storage: GlobalDisputes Winners (r:1 w:0) + // Storage: System Account (r:1 w:1) // 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 { - (92_016_000 as Weight) - // Standard Error: 21_000 - .saturating_add((258_000 as Weight).saturating_mul(r as Weight)) - // Standard Error: 301_000 - .saturating_add((23_377_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(6 as Weight)) - .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(d as Weight))) - .saturating_add(T::DbWeight::get().writes(5 as Weight)) - .saturating_add(T::DbWeight::get().writes((2 as Weight).saturating_mul(d as Weight))) + fn admin_move_market_to_resolved_categorical_disputed(r: u32) -> Weight { + (148_478_000 as Weight) + // Standard Error: 1_000 + .saturating_add((35_000 as Weight).saturating_mul(r as Weight)) + .saturating_add(T::DbWeight::get().reads(10 as Weight)) + .saturating_add(T::DbWeight::get().writes(8 as Weight)) } // Storage: MarketCommons Markets (r:1 w:1) // Storage: PredictionMarkets MarketIdsForEdit (r:1 w:0) // Storage: Balances Reserves (r:1 w:1) fn approve_market() -> Weight { - (41_000_000 as Weight) + (46_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } // Storage: MarketCommons Markets (r:1 w:0) // Storage: PredictionMarkets MarketIdsForEdit (r:1 w:1) - fn request_edit(r: u32) -> Weight { - (23_960_000 as Weight) - // Standard Error: 0 - .saturating_add((1_000 as Weight).saturating_mul(r as Weight)) + fn request_edit(_r: u32) -> Weight { + (24_170_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -217,9 +211,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Tokens Accounts (r:2 w:2) // Storage: Tokens TotalIssuance (r:2 w:2) fn buy_complete_set(a: u32) -> Weight { - (55_744_000 as Weight) - // Standard Error: 16_000 - .saturating_add((17_578_000 as Weight).saturating_mul(a as Weight)) + (52_875_000 as Weight) + // Standard Error: 4_000 + .saturating_add((17_255_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -231,9 +225,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerCloseTimeFrame (r:1 w:1) // Storage: MarketCommons Markets (r:0 w:1) fn create_market(m: u32) -> Weight { - (47_383_000 as Weight) - // Standard Error: 2_000 - .saturating_add((41_000 as Weight).saturating_mul(m as Weight)) + (46_289_000 as Weight) + // Standard Error: 0 + .saturating_add((24_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } @@ -242,9 +236,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerCloseTimeFrame (r:1 w:1) // Storage: Timestamp Now (r:1 w:0) fn edit_market(m: u32) -> Weight { - (40_572_000 as Weight) - // Standard Error: 1_000 - .saturating_add((34_000 as Weight).saturating_mul(m as Weight)) + (40_535_000 as Weight) + // Standard Error: 0 + .saturating_add((30_000 as Weight).saturating_mul(m as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } @@ -258,11 +252,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons MarketPool (r:1 w:1) // Storage: Swaps Pools (r:0 w:1) fn deploy_swap_pool_for_market_future_pool(a: u32, o: u32) -> Weight { - (59_265_000 as Weight) - // Standard Error: 63_000 - .saturating_add((27_729_000 as Weight).saturating_mul(a as Weight)) - // Standard Error: 62_000 - .saturating_add((391_000 as Weight).saturating_mul(o as Weight)) + (91_979_000 as Weight) + // Standard Error: 6_000 + .saturating_add((26_628_000 as Weight).saturating_mul(a as Weight)) + // Standard Error: 6_000 + .saturating_add((2_000 as Weight).saturating_mul(o as Weight)) .saturating_add(T::DbWeight::get().reads(8 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(7 as Weight)) @@ -277,9 +271,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons MarketPool (r:1 w:1) // Storage: Swaps Pools (r:0 w:1) fn deploy_swap_pool_for_market_open_pool(a: u32) -> Weight { - (72_610_000 as Weight) - // Standard Error: 135_000 - .saturating_add((28_739_000 as Weight).saturating_mul(a as Weight)) + (94_216_000 as Weight) + // Standard Error: 4_000 + .saturating_add((26_749_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(7 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(6 as Weight)) @@ -291,11 +285,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: GlobalDisputes Outcomes (r:7 w:7) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:2 w:2) fn start_global_dispute(m: u32, n: u32) -> Weight { - (93_550_000 as Weight) + (94_106_000 as Weight) // Standard Error: 0 - .saturating_add((27_000 as Weight).saturating_mul(m as Weight)) + .saturating_add((15_000 as Weight).saturating_mul(m as Weight)) // Standard Error: 0 - .saturating_add((16_000 as Weight).saturating_mul(n as Weight)) + .saturating_add((20_000 as Weight).saturating_mul(n as Weight)) .saturating_add(T::DbWeight::get().reads(12 as Weight)) .saturating_add(T::DbWeight::get().writes(10 as Weight)) } @@ -303,60 +297,60 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons Markets (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) fn dispute_authorized() -> Weight { - (47_000_000 as Weight) + (46_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } - // Storage: Balances Reserves (r:1 w:1) // Storage: MarketCommons Markets (r:1 w:1) + // Storage: Balances Reserves (r:1 w:1) // Storage: PredictionMarkets MarketIdsForEdit (r:0 w:1) fn handle_expired_advised_market() -> Weight { - (44_000_000 as Weight) + (49_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + // Storage: MarketCommons Markets (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: Swaps Pools (r:1 w:1) - // Storage: MarketCommons Markets (r:1 w:1) fn internal_resolve_categorical_reported() -> Weight { - (83_000_000 as Weight) + (85_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(4 as Weight)) } + // Storage: MarketCommons Markets (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) + // Storage: GlobalDisputes Winners (r:1 w:0) + // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) // Storage: Swaps Pools (r:1 w:1) - // Storage: MarketCommons Markets (r:1 w:1) - // Storage: System Account (r:1 w:1) - fn internal_resolve_categorical_disputed(d: u32) -> Weight { - (89_440_000 as Weight) - // Standard Error: 295_000 - .saturating_add((16_181_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(5 as Weight)) - .saturating_add(T::DbWeight::get().writes(4 as Weight)) + fn internal_resolve_categorical_disputed() -> Weight { + (118_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) } + // Storage: MarketCommons Markets (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) - // Storage: MarketCommons Markets (r:1 w:1) fn internal_resolve_scalar_reported() -> Weight { - (50_000_000 as Weight) + (56_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(3 as Weight)) } + // Storage: MarketCommons Markets (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) // Storage: PredictionMarkets Disputes (r:1 w:1) + // Storage: GlobalDisputes Winners (r:1 w:0) + // Storage: Authorized AuthorizedOutcomeReports (r:1 w:1) + // Storage: System Account (r:1 w:1) // Storage: MarketCommons MarketPool (r:1 w:0) - // Storage: MarketCommons Markets (r:1 w:1) - fn internal_resolve_scalar_disputed(d: u32) -> Weight { - (56_385_000 as Weight) - // Standard Error: 131_000 - .saturating_add((15_225_000 as Weight).saturating_mul(d as Weight)) - .saturating_add(T::DbWeight::get().reads(4 as Weight)) - .saturating_add(T::DbWeight::get().writes(3 as Weight)) + fn internal_resolve_scalar_disputed() -> Weight { + (100_000_000 as Weight) + .saturating_add(T::DbWeight::get().reads(7 as Weight)) + .saturating_add(T::DbWeight::get().writes(5 as Weight)) } // Storage: Timestamp Now (r:1 w:0) // Storage: PredictionMarkets MarketsCollectingSubsidy (r:1 w:1) @@ -374,9 +368,9 @@ impl WeightInfoZeitgeist for WeightInfo { } // Storage: PredictionMarkets MarketsCollectingSubsidy (r:1 w:1) fn process_subsidy_collecting_markets_raw(a: u32) -> Weight { - (3_535_000 as Weight) - // Standard Error: 6_000 - .saturating_add((176_000 as Weight).saturating_mul(a as Weight)) + (3_580_000 as Weight) + // Standard Error: 1_000 + .saturating_add((172_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(1 as Weight)) .saturating_add(T::DbWeight::get().writes(1 as Weight)) } @@ -394,7 +388,7 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: System Account (r:1 w:1) // Storage: Tokens TotalIssuance (r:2 w:2) fn redeem_shares_scalar() -> Weight { - (98_000_000 as Weight) + (95_000_000 as Weight) .saturating_add(T::DbWeight::get().reads(6 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -403,12 +397,14 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketIdsPerCloseTimeFrame (r:1 w:1) // Storage: Balances Reserves (r:1 w:1) // Storage: PredictionMarkets MarketIdsForEdit (r:0 w:1) - fn reject_market(c: u32, o: u32, _r: u32) -> Weight { - (60_929_000 as Weight) - // Standard Error: 1_000 - .saturating_add((8_000 as Weight).saturating_mul(c as Weight)) - // Standard Error: 1_000 - .saturating_add((15_000 as Weight).saturating_mul(o as Weight)) + fn reject_market(c: u32, o: u32, r: u32) -> Weight { + (78_886_000 as Weight) + // Standard Error: 0 + .saturating_add((16_000 as Weight).saturating_mul(c as Weight)) + // Standard Error: 0 + .saturating_add((21_000 as Weight).saturating_mul(o as Weight)) + // Standard Error: 0 + .saturating_add((2_000 as Weight).saturating_mul(r as Weight)) .saturating_add(T::DbWeight::get().reads(4 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -416,7 +412,7 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Timestamp Now (r:1 w:0) // Storage: PredictionMarkets MarketIdsPerReportBlock (r:1 w:1) fn report(_m: u32) -> Weight { - (31_154_000 as Weight) + (31_024_000 as Weight) .saturating_add(T::DbWeight::get().reads(3 as Weight)) .saturating_add(T::DbWeight::get().writes(2 as Weight)) } @@ -425,9 +421,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: Tokens Accounts (r:2 w:2) // Storage: Tokens TotalIssuance (r:2 w:2) fn sell_complete_set(a: u32) -> Weight { - (44_770_000 as Weight) - // Standard Error: 12_000 - .saturating_add((21_432_000 as Weight).saturating_mul(a as Weight)) + (40_368_000 as Weight) + // Standard Error: 4_000 + .saturating_add((21_523_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((2 as Weight).saturating_mul(a as Weight))) .saturating_add(T::DbWeight::get().writes(1 as Weight)) @@ -440,9 +436,9 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: PredictionMarkets MarketsCollectingSubsidy (r:1 w:1) // Storage: Swaps Pools (r:0 w:1) fn start_subsidy(a: u32) -> Weight { - (34_382_000 as Weight) - // Standard Error: 1_000 - .saturating_add((36_000 as Weight).saturating_mul(a as Weight)) + (33_451_000 as Weight) + // Standard Error: 0 + .saturating_add((52_000 as Weight).saturating_mul(a as Weight)) .saturating_add(T::DbWeight::get().reads(5 as Weight)) .saturating_add(T::DbWeight::get().writes(5 as Weight)) } @@ -450,11 +446,11 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons Markets (r:32 w:0) // Storage: PredictionMarkets MarketIdsPerOpenTimeFrame (r:1 w:1) fn market_status_manager(b: u32, f: u32) -> Weight { - (7_909_000 as Weight) - // Standard Error: 10_000 - .saturating_add((4_309_000 as Weight).saturating_mul(b as Weight)) - // Standard Error: 10_000 - .saturating_add((4_287_000 as Weight).saturating_mul(f as Weight)) + (15_414_000 as Weight) + // Standard Error: 2_000 + .saturating_add((4_284_000 as Weight).saturating_mul(b as Weight)) + // Standard Error: 2_000 + .saturating_add((4_380_000 as Weight).saturating_mul(f as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(b as Weight))) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(f as Weight))) @@ -464,10 +460,10 @@ impl WeightInfoZeitgeist for WeightInfo { // Storage: MarketCommons Markets (r:32 w:0) // Storage: PredictionMarkets MarketIdsPerDisputeBlock (r:1 w:1) fn market_resolution_manager(r: u32, d: u32) -> Weight { - (8_808_000 as Weight) - // Standard Error: 11_000 - .saturating_add((4_290_000 as Weight).saturating_mul(r as Weight)) - // Standard Error: 11_000 + (17_183_000 as Weight) + // Standard Error: 2_000 + .saturating_add((4_209_000 as Weight).saturating_mul(r as Weight)) + // Standard Error: 2_000 .saturating_add((4_285_000 as Weight).saturating_mul(d as Weight)) .saturating_add(T::DbWeight::get().reads(2 as Weight)) .saturating_add(T::DbWeight::get().reads((1 as Weight).saturating_mul(r as Weight))) From b41af6ac3e873f08706b5c584f7bb9a86e65a542 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 10 Jan 2023 09:54:38 +0100 Subject: [PATCH 89/93] remove unused error --- zrml/authorized/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/zrml/authorized/src/lib.rs b/zrml/authorized/src/lib.rs index bb7361ebd..d33cc2789 100644 --- a/zrml/authorized/src/lib.rs +++ b/zrml/authorized/src/lib.rs @@ -160,8 +160,6 @@ mod pallet { OnlyOneDisputeAllowed, /// The report does not match the market's type. OutcomeMismatch, - /// The market should be reported at this point. - MarketIsNotReported, } #[pallet::event] From aea06f8129886323302d982fb898f92969451fa3 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 10 Jan 2023 10:01:52 +0100 Subject: [PATCH 90/93] test only one dispute error --- zrml/authorized/src/tests.rs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index ea3de11fb..0b3e56cc1 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -26,7 +26,7 @@ use crate::{ use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; use zeitgeist_primitives::{ traits::DisputeApi, - types::{AuthorityReport, MarketDisputeMechanism, MarketStatus, OutcomeReport}, + types::{AuthorityReport, MarketDisputeMechanism, MarketStatus, OutcomeReport, MarketDispute}, }; use zrml_market_commons::Markets; @@ -156,6 +156,21 @@ fn authorize_market_outcome_fails_on_unauthorized_account() { }); } +#[test] +fn on_dispute_fails_if_disputes_is_not_empty() { + ExtBuilder::default().build().execute_with(|| { + let dispute = MarketDispute { + by: crate::mock::ALICE, + at: 0, + outcome: OutcomeReport::Scalar(1), + }; + assert_noop!( + Authorized::on_dispute(&[dispute], &0, &market_mock::()), + Error::::OnlyOneDisputeAllowed + ); + }); +} + #[test] fn on_resolution_fails_if_no_report_was_submitted() { ExtBuilder::default().build().execute_with(|| { From 7ba0801690667e3d0383f2779296e979cd6859b0 Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 10 Jan 2023 10:13:30 +0100 Subject: [PATCH 91/93] remove unused error --- zrml/prediction-markets/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index ff1a15c12..e95fd1ab7 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -1557,8 +1557,6 @@ mod pallet { /// Someone is trying to call `dispute` with the same outcome that is currently /// registered on-chain. CannotDisputeSameOutcome, - /// The market dispute mechanism has not failed. - DisputeMechanismHasNotFailed, /// Only creator is able to edit the market. EditorNotCreator, /// EditReason's length greater than MaxEditReasonLen. From cfc576ae4f3af61f09271b3f98c1fd7f12262e1d Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 10 Jan 2023 10:15:23 +0100 Subject: [PATCH 92/93] remove unused event --- zrml/prediction-markets/src/lib.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index e95fd1ab7..9695db7c9 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -1659,8 +1659,6 @@ mod pallet { BadOnInitialize, /// A complete set of assets has been bought \[market_id, amount_per_asset, buyer\] BoughtCompleteSet(MarketIdOf, BalanceOf, ::AccountId), - /// A failed market dispute mechansim finally resolved \[market_id\] - FailedDisputeMechanismResolved(MarketIdOf), /// A market has been approved \[market_id, new_market_status\] MarketApproved(MarketIdOf, MarketStatus), /// A market has been created \[market_id, market_account, market\] From d328b2f929c65ee92e95bf9eb629b4be0cc5e9ec Mon Sep 17 00:00:00 2001 From: Chralt98 Date: Tue, 10 Jan 2023 10:30:58 +0100 Subject: [PATCH 93/93] cargo fmt --- zrml/authorized/src/tests.rs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/zrml/authorized/src/tests.rs b/zrml/authorized/src/tests.rs index 0b3e56cc1..7cd33883c 100644 --- a/zrml/authorized/src/tests.rs +++ b/zrml/authorized/src/tests.rs @@ -26,7 +26,7 @@ use crate::{ use frame_support::{assert_noop, assert_ok, dispatch::DispatchError}; use zeitgeist_primitives::{ traits::DisputeApi, - types::{AuthorityReport, MarketDisputeMechanism, MarketStatus, OutcomeReport, MarketDispute}, + types::{AuthorityReport, MarketDispute, MarketDisputeMechanism, MarketStatus, OutcomeReport}, }; use zrml_market_commons::Markets; @@ -159,11 +159,8 @@ fn authorize_market_outcome_fails_on_unauthorized_account() { #[test] fn on_dispute_fails_if_disputes_is_not_empty() { ExtBuilder::default().build().execute_with(|| { - let dispute = MarketDispute { - by: crate::mock::ALICE, - at: 0, - outcome: OutcomeReport::Scalar(1), - }; + let dispute = + MarketDispute { by: crate::mock::ALICE, at: 0, outcome: OutcomeReport::Scalar(1) }; assert_noop!( Authorized::on_dispute(&[dispute], &0, &market_mock::()), Error::::OnlyOneDisputeAllowed