diff --git a/primitives/src/traits/market_builder.rs b/primitives/src/traits/market_builder.rs index c956bf7fc..7f682c8d7 100644 --- a/primitives/src/traits/market_builder.rs +++ b/primitives/src/traits/market_builder.rs @@ -23,7 +23,7 @@ use alloc::vec::Vec; use sp_runtime::{DispatchError, Perbill}; macro_rules! builder_methods { - ($($field:ident: $type:ty),*) => { + ($($field:ident: $type:ty),* $(,)?) => { $(fn $field(&mut self, $field: $type) -> &mut Self;)* } } @@ -32,11 +32,11 @@ macro_rules! builder_methods { /// the usual calling pattern is: /// /// ```ignore -/// let builder = MarketBuilderImpl::new(args...); +/// let builder = MarketBuilderImpl::new(); /// builder.field1(value1).field2(value2); /// builder.clone().build() /// ``` -pub trait MarketBuilder { +pub trait MarketBuilderTrait { fn build(self) -> Result, DispatchError>; builder_methods! { @@ -56,6 +56,6 @@ pub trait MarketBuilder { resolved_outcome: Option, dispute_mechanism: Option, bonds: MarketBonds, - early_close: Option> + early_close: Option>, } } diff --git a/primitives/src/traits/market_commons_pallet_api.rs b/primitives/src/traits/market_commons_pallet_api.rs index aa07cb2f5..dac3402f9 100644 --- a/primitives/src/traits/market_commons_pallet_api.rs +++ b/primitives/src/traits/market_commons_pallet_api.rs @@ -19,7 +19,7 @@ #![allow(clippy::type_complexity)] use crate::{ - traits::MarketBuilder, + traits::MarketBuilderTrait, types::{Asset, Market, PoolId}, }; use frame_support::{ @@ -100,7 +100,7 @@ pub trait MarketCommonsPalletApi { market_builder: U, ) -> Result<(Self::MarketId, MarketOf), DispatchError> where - U: MarketBuilder< + U: MarketBuilderTrait< Self::AccountId, Self::Balance, Self::BlockNumber, diff --git a/primitives/src/types.rs b/primitives/src/types.rs index e2460cd9c..616357787 100644 --- a/primitives/src/types.rs +++ b/primitives/src/types.rs @@ -17,13 +17,11 @@ // along with Zeitgeist. If not, see . pub mod multi_hash; -pub mod primitive_market_builder; pub mod result_with_weight_info; pub mod type_aliases; pub mod xcm_metadata; pub use multi_hash::*; -pub use primitive_market_builder::*; pub use result_with_weight_info::*; pub use type_aliases::*; pub use xcm_metadata::*; diff --git a/primitives/src/types/primitive_market_builder.rs b/primitives/src/types/primitive_market_builder.rs deleted file mode 100644 index 34b0ea959..000000000 --- a/primitives/src/types/primitive_market_builder.rs +++ /dev/null @@ -1,122 +0,0 @@ -// Copyright 2024 Forecasting Technologies LTD. -// -// 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 . - -use crate::{ - traits::MarketBuilder, - types::{ - Deadlines, EarlyClose, Market, MarketBonds, MarketCreation, MarketDisputeMechanism, - MarketPeriod, MarketStatus, MarketType, OutcomeReport, Report, ScoringRule, - }, -}; -use alloc::vec::Vec; -use sp_runtime::{DispatchError, Perbill}; - -/// A sample market builder struct used for testing. No verification is done when calling `build()`; -/// use at your own risk! -/// -/// Fields are deliberately kept public to allow the straightforward construction of builder objects -/// in spots where correctness isn't the primary concern. -/// -/// # Generics -/// -/// * `AI`: The account ID type. -/// * `BA`: The balance type. -/// * `BN`: The block number type. -/// * `M`: The moment/time type. -/// * `A`: The asset type. -/// * `MI`: The market ID type. -#[derive(Clone)] -pub struct PrimitiveMarketBuilder { - pub market_id: Option, - pub base_asset: A, - pub creator: AI, - pub creation: MarketCreation, - pub creator_fee: Perbill, - pub oracle: AI, - pub metadata: Vec, - pub market_type: MarketType, - pub period: MarketPeriod, - pub deadlines: Deadlines, - pub scoring_rule: ScoringRule, - pub status: MarketStatus, - pub report: Option>, - pub resolved_outcome: Option, - pub dispute_mechanism: Option, - pub bonds: MarketBonds, - pub early_close: Option>, -} - -macro_rules! impl_builder_methods { - ($($field:ident: $type:ty),*) => { - $( - fn $field(&mut self, $field: $type) -> &mut Self { - self.$field = $field; - self - } - )* - } -} - -impl MarketBuilder - for PrimitiveMarketBuilder -{ - fn build(self) -> Result, DispatchError> { - Ok(Market { - market_id: self.market_id.unwrap(), - base_asset: self.base_asset, - creator: self.creator, - creation: self.creation, - creator_fee: self.creator_fee, - oracle: self.oracle, - metadata: self.metadata, - market_type: self.market_type, - period: self.period, - deadlines: self.deadlines, - scoring_rule: self.scoring_rule, - status: self.status, - report: self.report, - resolved_outcome: self.resolved_outcome, - dispute_mechanism: self.dispute_mechanism, - bonds: self.bonds, - early_close: self.early_close, - }) - } - - fn market_id(&mut self, market_id: MI) -> &mut Self { - self.market_id = Some(market_id); - self - } - - impl_builder_methods! { - base_asset: A, - creator: AI, - creation: MarketCreation, - creator_fee: Perbill, - oracle: AI, - metadata: Vec, - market_type: MarketType, - period: MarketPeriod, - deadlines: Deadlines, - scoring_rule: ScoringRule, - status: MarketStatus, - report: Option>, - resolved_outcome: Option, - dispute_mechanism: Option, - bonds: MarketBonds, - early_close: Option> - } -} diff --git a/zrml/market-commons/src/lib.rs b/zrml/market-commons/src/lib.rs index ef4470be5..9d05179c2 100644 --- a/zrml/market-commons/src/lib.rs +++ b/zrml/market-commons/src/lib.rs @@ -24,6 +24,7 @@ extern crate alloc; pub mod migrations; mod mock; mod tests; +pub mod types; pub use pallet::*; pub use zeitgeist_primitives::traits::MarketCommonsPalletApi; @@ -50,8 +51,8 @@ mod pallet { }; use zeitgeist_primitives::{ math::checked_ops_res::CheckedAddRes, - traits::MarketBuilder, - types::{Asset, Market, PoolId}, + traits::MarketBuilderTrait, + types::{Asset, Deadlines, EarlyClose, Market, MarketBonds, MarketPeriod, PoolId, Report}, }; /// The current storage version. @@ -61,6 +62,7 @@ mod pallet { pub(crate) type AssetOf = Asset>; pub(crate) type BalanceOf = ::Balance; pub(crate) type BlockNumberOf = ::BlockNumber; + pub(crate) type MarketIdOf = ::MarketId; pub(crate) type MarketOf = Market< AccountIdOf, BalanceOf, @@ -69,8 +71,12 @@ mod pallet { AssetOf, MarketIdOf, >; - pub type MarketIdOf = ::MarketId; - pub type MomentOf = <::Timestamp as frame_support::traits::Time>::Moment; + pub(crate) type MomentOf = <::Timestamp as frame_support::traits::Time>::Moment; + pub(crate) type DeadlinesOf = Deadlines>; + pub(crate) type EarlyCloseOf = EarlyClose, MomentOf>; + pub(crate) type MarketBondsOf = MarketBonds, BalanceOf>; + pub(crate) type MarketPeriodOf = MarketPeriod, MomentOf>; + pub(crate) type ReportOf = Report, BlockNumberOf>; #[pallet::call] impl Pallet {} @@ -112,6 +118,8 @@ mod pallet { NoReport, /// There's a pool registered for this market already. PoolAlreadyExists, + /// Unexpectedly failed to build a market due to missing data. + IncompleteMarketBuilder, } #[pallet::hooks] @@ -193,7 +201,7 @@ mod pallet { mut market_builder: U, ) -> Result<(Self::MarketId, MarketOf), DispatchError> where - U: MarketBuilder< + U: MarketBuilderTrait< Self::AccountId, Self::Balance, Self::BlockNumber, diff --git a/zrml/market-commons/src/tests.rs b/zrml/market-commons/src/tests.rs index b74fdfd77..793559b44 100644 --- a/zrml/market-commons/src/tests.rs +++ b/zrml/market-commons/src/tests.rs @@ -20,60 +20,51 @@ use crate::{ mock::{ExtBuilder, MarketCommons, Runtime}, - AccountIdOf, AssetOf, BalanceOf, BlockNumberOf, MarketCounter, MarketIdOf, Markets, MomentOf, + types::MarketBuilder, + AccountIdOf, MarketCounter, Markets, }; use frame_support::{assert_err, assert_noop, assert_ok}; use sp_runtime::{DispatchError, Perbill}; use zeitgeist_primitives::{ - traits::{MarketBuilder, MarketCommonsPalletApi}, + traits::{MarketBuilderTrait, MarketCommonsPalletApi}, types::{ Asset, Deadlines, MarketBonds, MarketCreation, MarketDisputeMechanism, MarketPeriod, - MarketStatus, MarketType, PrimitiveMarketBuilder, ScoringRule, + MarketStatus, MarketType, ScoringRule, }, }; -type PrimitiveMarketBuilderOf = PrimitiveMarketBuilder< - AccountIdOf, - BalanceOf, - BlockNumberOf, - MomentOf, - AssetOf, - MarketIdOf, ->; - // Creates a sample market builder. We use the `oracle` field to tell markets apart from each other. -// For testing purposes, we allow `market_id` to be defined, as well. -fn create_market_builder(oracle: AccountIdOf) -> PrimitiveMarketBuilderOf { - PrimitiveMarketBuilder { - market_id: None, - base_asset: Asset::Ztg, - creation: MarketCreation::Permissionless, - creator_fee: Perbill::zero(), - creator: 0, - market_type: MarketType::Scalar(0..=100), - dispute_mechanism: Some(MarketDisputeMechanism::Authorized), - metadata: vec![], - oracle, - period: MarketPeriod::Block(0..100), - deadlines: Deadlines { +fn create_market_builder(oracle: AccountIdOf) -> MarketBuilder { + let mut market_builder = MarketBuilder::new(); + market_builder + .base_asset(Asset::Ztg) + .creation(MarketCreation::Permissionless) + .creator_fee(Perbill::zero()) + .creator(0) + .market_type(MarketType::Scalar(0..=100)) + .dispute_mechanism(Some(MarketDisputeMechanism::Authorized)) + .metadata(vec![]) + .oracle(oracle) + .period(MarketPeriod::Block(0..100)) + .deadlines(Deadlines { grace_period: 1_u64, oracle_duration: 1_u64, dispute_duration: 1_u64, - }, - report: None, - resolved_outcome: None, - scoring_rule: ScoringRule::Lmsr, - status: MarketStatus::Disputed, - bonds: MarketBonds { + }) + .report(None) + .resolved_outcome(None) + .scoring_rule(ScoringRule::Lmsr) + .status(MarketStatus::Disputed) + .bonds(MarketBonds { creation: None, oracle: None, outsider: None, dispute: None, close_dispute: None, close_request: None, - }, - early_close: None, - } + }) + .early_close(None); + market_builder } #[test] diff --git a/zrml/prediction-markets/src/lib.rs b/zrml/prediction-markets/src/lib.rs index 814eae9cd..851b6f1df 100644 --- a/zrml/prediction-markets/src/lib.rs +++ b/zrml/prediction-markets/src/lib.rs @@ -28,7 +28,6 @@ pub mod migrations; pub mod mock; pub mod orml_asset_registry; mod tests; -mod types; pub mod weights; pub use pallet::*; @@ -56,7 +55,6 @@ mod pallet { #[cfg(feature = "parachain")] use {orml_traits::asset_registry::Inspect, zeitgeist_primitives::types::CustomMetadata}; - use crate::types::PredictionMarketBuilder; use orml_traits::{MultiCurrency, NamedMultiReservableCurrency}; use sp_arithmetic::per_things::{Perbill, Percent}; use sp_runtime::{ @@ -67,7 +65,7 @@ mod pallet { constants::MILLISECS_PER_BLOCK, traits::{ CompleteSetOperationsApi, DeployPoolApi, DisputeApi, DisputeMaxWeightApi, - DisputeResolutionApi, MarketBuilder, ZeitgeistAssetManager, + DisputeResolutionApi, MarketBuilderTrait, ZeitgeistAssetManager, }, types::{ Asset, Bond, Deadlines, EarlyClose, EarlyCloseState, GlobalDisputeItem, Market, @@ -78,7 +76,7 @@ mod pallet { }; use zrml_global_disputes::{types::InitialItem, GlobalDisputesPalletApi}; use zrml_liquidity_mining::LiquidityMiningPalletApi; - use zrml_market_commons::MarketCommonsPalletApi; + use zrml_market_commons::{types::MarketBuilder, MarketCommonsPalletApi}; /// The current storage version. const STORAGE_VERSION: StorageVersion = StorageVersion::new(8); @@ -95,7 +93,6 @@ mod pallet { pub(crate) type BlockNumberOf = ::BlockNumber; pub(crate) type CacheSize = ConstU32<64>; pub(crate) type DeadlinesOf = Deadlines>; - pub(crate) type EarlyCloseOf = EarlyClose, MomentOf>; pub(crate) type EditReason = BoundedVec::MaxEditReasonLen>; pub(crate) type InitialItemOf = InitialItem, BalanceOf>; pub(crate) type MarketBondsOf = MarketBonds, BalanceOf>; @@ -1854,8 +1851,6 @@ mod pallet { MarketNotInCloseTimeFrameList, /// The market period end was not already reached yet. MarketPeriodEndNotAlreadyReachedYet, - /// Unexpectedly failed to build a market due to missing data. - IncompleteMarketBuilder, } #[pallet::event] @@ -2895,7 +2890,7 @@ mod pallet { report: Option>, resolved_outcome: Option, bonds: MarketBondsOf, - ) -> Result, DispatchError> { + ) -> Result, DispatchError> { let valid_base_asset = match base_asset { Asset::Ztg => true, #[cfg(feature = "parachain")] @@ -2921,7 +2916,7 @@ mod pallet { MarketCreation::Permissionless => MarketStatus::Active, MarketCreation::Advised => MarketStatus::Proposed, }; - let mut market_builder = PredictionMarketBuilder::new(); + let mut market_builder = MarketBuilder::new(); market_builder .base_asset(base_asset) .creator(creator) diff --git a/zrml/prediction-markets/src/types/market_builder.rs b/zrml/prediction-markets/src/types/market_builder.rs deleted file mode 100644 index 4afdea804..000000000 --- a/zrml/prediction-markets/src/types/market_builder.rs +++ /dev/null @@ -1,158 +0,0 @@ -// Copyright 2024 Forecasting Technologies LTD. -// -// 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 . - -use crate::{ - AccountIdOf, AssetOf, BalanceOf, BlockNumberOf, Config, DeadlinesOf, EarlyCloseOf, Error, - MarketBondsOf, MarketIdOf, MarketOf, MarketPeriodOf, MomentOf, ReportOf, -}; -use alloc::vec::Vec; -use sp_runtime::{DispatchError, Perbill}; -use zeitgeist_primitives::{ - traits::MarketBuilder, - types::{ - Market, MarketCreation, MarketDisputeMechanism, MarketStatus, MarketType, OutcomeReport, - ScoringRule, - }, -}; - -/// Fully-fledged mutably referenced market builder struct. -#[derive(Clone)] -pub(crate) struct PredictionMarketBuilder -where - T: Config, -{ - market_id: Option>, - base_asset: Option>, - creator: Option>, - creation: Option, - creator_fee: Option, - oracle: Option>, - metadata: Option>, - market_type: Option, - period: Option>, - deadlines: Option>, - scoring_rule: Option, - status: Option, - report: Option>>, - resolved_outcome: Option>, - dispute_mechanism: Option>, - bonds: Option>, - early_close: Option>>, -} - -impl PredictionMarketBuilder -where - T: Config, -{ - pub(crate) fn new() -> Self { - PredictionMarketBuilder { - market_id: None, - base_asset: None, - creator: None, - creation: None, - creator_fee: None, - oracle: None, - metadata: None, - market_type: None, - period: None, - deadlines: None, - scoring_rule: None, - status: None, - report: None, - resolved_outcome: None, - dispute_mechanism: None, - bonds: None, - early_close: None, - } - } -} - -/// Implements setter methods for a mutably referenced builder struct. Fields are specified using -/// the pattern `{ field: type, ... }`. -macro_rules! impl_builder_methods { - ($($field:ident: $type:ty),*) => { - $( - fn $field(&mut self, $field: $type) -> &mut Self { - self.$field = Some($field); - self - } - )* - } -} - -/// Unwraps `opt` and throws `IncompleteMarketBuilder` in case of failure. -fn ok_or_incomplete(opt: Option) -> Result -where - T: Config, -{ - opt.ok_or(Error::::IncompleteMarketBuilder.into()) -} - -impl - MarketBuilder< - AccountIdOf, - BalanceOf, - BlockNumberOf, - MomentOf, - AssetOf, - MarketIdOf, - > for PredictionMarketBuilder -where - T: Config, -{ - fn build(self) -> Result, DispatchError> { - Ok(Market { - market_id: ok_or_incomplete::(self.market_id)?, - base_asset: ok_or_incomplete::(self.base_asset)?, - creator: ok_or_incomplete::(self.creator)?, - creation: ok_or_incomplete::(self.creation)?, - creator_fee: ok_or_incomplete::(self.creator_fee)?, - oracle: ok_or_incomplete::(self.oracle)?, - metadata: ok_or_incomplete::(self.metadata)?, - market_type: ok_or_incomplete::(self.market_type)?, - period: ok_or_incomplete::(self.period)?, - deadlines: ok_or_incomplete::(self.deadlines)?, - scoring_rule: ok_or_incomplete::(self.scoring_rule)?, - status: ok_or_incomplete::(self.status)?, - report: ok_or_incomplete::(self.report)?, - resolved_outcome: ok_or_incomplete::(self.resolved_outcome)?, - dispute_mechanism: ok_or_incomplete::(self.dispute_mechanism)?, - bonds: ok_or_incomplete::(self.bonds)?, - early_close: ok_or_incomplete::(self.early_close)?, - }) - } - - impl_builder_methods! { - market_id: MarketIdOf, - base_asset: AssetOf, - creator: AccountIdOf, - creation: MarketCreation, - creator_fee: Perbill, - oracle: AccountIdOf, - metadata: Vec, - market_type: MarketType, - period: MarketPeriodOf, - deadlines: DeadlinesOf, - scoring_rule: ScoringRule, - status: MarketStatus, - report: Option>, - resolved_outcome: Option, - dispute_mechanism: Option, - bonds: MarketBondsOf, - early_close: Option> - } -} diff --git a/zrml/prediction-markets/src/types/mod.rs b/zrml/prediction-markets/src/types/mod.rs deleted file mode 100644 index 47baa4a61..000000000 --- a/zrml/prediction-markets/src/types/mod.rs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2024 Forecasting Technologies LTD. -// -// 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 . - -mod market_builder; - -pub(crate) use market_builder::*;