Skip to content

Commit

Permalink
Implement Scheduler mock
Browse files Browse the repository at this point in the history
  • Loading branch information
maltekliemann committed Oct 17, 2024
1 parent 0e0080b commit 26d5b8a
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 25 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 5 additions & 2 deletions runtime/common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1207,9 +1207,12 @@ macro_rules! impl_config_traits {
}

impl zrml_futarchy::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type MultiCurrency = AssetManager;
type MultiCurrency = Currencies;
type MinDuration = MinDuration;
type OracleQuery = MockOracleQuery;
type Preimages = Preimage;
type RuntimeEvent = RuntimeEvent;
type Scheduler = Scheduler;
type SubmitOrigin = EnsureRoot<AccountId>;
}

Expand Down
3 changes: 3 additions & 0 deletions runtime/zeitgeist/src/parameters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,9 @@ parameter_types! {
/// The maximum number of public proposals that can exist at any time.
pub const MaxProposals: u32 = 100;

// Futarchy
pub const MinDuration: BlockNumber = 7 * BLOCKS_PER_DAY;

// Hybrid Router parameters
pub const HybridRouterPalletId: PalletId = HYBRID_ROUTER_PALLET_ID;
/// Maximum number of orders that can be placed in a single trade transaction.
Expand Down
5 changes: 4 additions & 1 deletion zrml/futarchy/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ frame-benchmarking = { workspace = true, optional = true }
frame-support = { workspace = true }
frame-system = { workspace = true }
orml-traits = { workspace = true }
pallet-preimage = { workspace = true }
parity-scale-codec = { workspace = true, features = ["derive", "max-encoded-len"] }
scale-info = { workspace = true, features = ["derive"] }
sp-runtime = { workspace = true }
Expand All @@ -15,6 +14,8 @@ env_logger = { workspace = true, optional = true }
orml-currencies = { workspace = true, optional = true }
orml-tokens = { workspace = true, optional = true }
pallet-balances = { workspace = true, optional = true }
pallet-preimage = { workspace = true }
pallet-scheduler = { workspace = true, optional = true }
pallet-timestamp = { workspace = true, optional = true }
sp-io = { workspace = true, optional = true }

Expand All @@ -30,6 +31,8 @@ mock = [
"orml-tokens/default",
"sp-io/default",
"pallet-balances/default",
"pallet-preimage/default",
"pallet-scheduler/default",
"pallet-timestamp/default",
"zeitgeist-primitives/mock",
]
Expand Down
14 changes: 9 additions & 5 deletions zrml/futarchy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ mod pallet {
use crate::{traits::OracleQuery, types::Proposal};
use core::marker::PhantomData;
use frame_support::{
dispatch::RawOrigin,
ensure,
pallet_prelude::{EnsureOrigin, IsType, StorageMap, StorageVersion, ValueQuery},
pallet_prelude::{EnsureOrigin, IsType, StorageMap, StorageVersion, ValueQuery, Weight},
require_transactional,
traits::{
schedule::{v3::Anon as ScheduleAnon, DispatchTime},
Expand All @@ -47,7 +48,6 @@ mod pallet {
traits::{ConstU32, Get},
DispatchResult, Saturating,
};
use frame_support::pallet_prelude::Weight;use frame_support::dispatch::RawOrigin;

#[pallet::config]
pub trait Config: frame_system::Config {
Expand All @@ -58,7 +58,7 @@ mod pallet {
type OracleQuery: OracleQuery;

/// Preimage interface for acquiring call data.
type Preimages: QueryPreimage + StorePreimage;
type Preimages: QueryPreimage + StorePreimage; // TODO Why do we even need this?

type RuntimeEvent: From<Event<Self>> + IsType<<Self as frame_system::Config>::RuntimeEvent>;

Expand Down Expand Up @@ -116,6 +116,7 @@ mod pallet {
pub enum Error<T> {
/// The cache for this particular block is full. Try another block.
CacheFull,

/// The specified duration must be at least equal to `MinDuration`.
DurationTooShort,
}
Expand All @@ -132,6 +133,7 @@ mod pallet {
proposal: ProposalOf<T>,
) -> DispatchResult {
T::SubmitOrigin::ensure_origin(origin)?;

Self::do_submit_proposal(duration, proposal)
}
}
Expand All @@ -147,9 +149,11 @@ mod pallet {
let now = frame_system::Pallet::<T>::block_number();
let to_be_scheduled_at = now.saturating_add(duration);

Ok(Proposals::<T>::try_mutate(to_be_scheduled_at, |proposals| {
let try_mutate_result = Proposals::<T>::try_mutate(to_be_scheduled_at, |proposals| {
proposals.try_push(proposal).map_err(|_| Error::<T>::CacheFull)
})?)
});

Ok(try_mutate_result?)
}

/// Evaluates `proposal` using the specified oracle and schedules the contained call if the
Expand Down
35 changes: 27 additions & 8 deletions zrml/futarchy/src/mock/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,36 @@
// along with Zeitgeist. If not, see <https://www.gnu.org/licenses/>.

use crate as zrml_futarchy;
use crate::mock::types::MockOracleQuery;
use frame_support::{construct_runtime, parameter_types, traits::Everything};
use crate::mock::types::{MockOracleQuery, MockScheduler};
use frame_support::{
construct_runtime,
pallet_prelude::Weight,
parameter_types,
traits::{EqualPrivilegeOnly, Everything},
};
use frame_system::{mocking::MockBlock, EnsureRoot};
use sp_runtime::traits::{BlakeTwo256, ConstU32, IdentityLookup};
use sp_runtime::{
traits::{BlakeTwo256, ConstU32, IdentityLookup},
Perbill,
};
use zeitgeist_primitives::{
constants::mock::{
BlockHashCount, ExistentialDeposit, ExistentialDeposits, GetNativeCurrencyId, MaxLocks,
MaxReserves, MinimumPeriod,
constants::{
mock::{
BlockHashCount, ExistentialDeposit, ExistentialDeposits, GetNativeCurrencyId, MaxLocks,
MaxReserves, MinimumPeriod,
},
BLOCKS_PER_MINUTE,
},
types::{
AccountIdTest, Amount, Balance, BasicCurrencyAdapter, BlockNumber, CurrencyId, Hash, Moment,
},
types::{AccountIdTest, Amount, Balance, BasicCurrencyAdapter, CurrencyId, Hash, Moment},
};

parameter_types! {
// zrml-futarchy
pub const MinDuration: BlockNumber = 10;

// pallet-preimage
pub const PreimageBaseDeposit: Balance = 0;
pub const PreimageByteDeposit: Balance = 0;
}
Expand All @@ -47,9 +64,11 @@ construct_runtime! {

impl zrml_futarchy::Config for Runtime {
type MultiCurrency = Currencies;
type MinDuration = MinDuration;
type OracleQuery = MockOracleQuery;
type Preimages = Preimage;
type RuntimeEvent = RuntimeEvent;
type Scheduler = MockScheduler;
type SubmitOrigin = EnsureRoot<<Runtime as frame_system::Config>::AccountId>;
}

Expand Down Expand Up @@ -80,7 +99,7 @@ impl pallet_preimage::Config for Runtime {
type WeightInfo = ();
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type ManagerOrigin = EnsureRoot<AccountIdTest>;
type ManagerOrigin = EnsureRoot<<Runtime as frame_system::Config>::AccountId>;
type BaseDeposit = PreimageBaseDeposit;
type ByteDeposit = PreimageByteDeposit;
}
Expand Down
2 changes: 2 additions & 0 deletions zrml/futarchy/src/mock/types/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
pub mod oracle_query;
pub mod scheduler;

pub use oracle_query::MockOracleQuery;
pub use scheduler::MockScheduler;
15 changes: 6 additions & 9 deletions zrml/futarchy/src/mock/types/oracle_query.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
use crate::traits::OracleQuery;
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use alloc::fmt::Debug;
use frame_support::pallet_prelude::Weight;

#[derive(Decode, Encode, MaxEncodedLen, TypeInfo)]
#[derive(Clone, Debug, Decode, Encode, MaxEncodedLen, PartialEq, TypeInfo)]
pub struct MockOracleQuery {
weight: Weight,
value: bool,
}

impl MockOracleQuery {
fn new(value: bool) -> Self {
Self { value }
}
}

impl OracleQuery for MockOracleQuery {
fn evaluate(&self) -> bool {
self.value
fn evaluate(&self) -> (Weight, bool) {
(self.weight, self.value)
}
}
79 changes: 79 additions & 0 deletions zrml/futarchy/src/mock/types/scheduler.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
use crate::{mock::runtime::Runtime, BoundedCallOf, CallOf};
use core::cell::RefCell;
use frame_support::traits::schedule::{v3::Anon as ScheduleAnon, DispatchTime, Period, Priority};
use frame_system::{
pallet_prelude::{BlockNumberFor, OriginFor},
Call, Origin,
};
use sp_runtime::{traits::Bounded, DispatchError, DispatchResult};

pub struct MockScheduler;

impl MockScheduler {
fn set_return_value(value: DispatchResult) {
SCHEDULER_RETURN_VALUE.with(|v| *v.borrow_mut() = Some(value));
}

fn called_once_with(
when: DispatchTime<BlockNumberFor<Runtime>>,
call: BoundedCallOf<Runtime>,
) -> bool {
if SCHEDULER_CALL_DATA.with(|value| value.borrow().len()) != 1 {
return false;
}

let args = SCHEDULER_CALL_DATA
.with(|value| value.borrow().first().expect("can't be empty").clone());

args == SchedulerCallData { when, call }
}
}

#[derive(Clone, PartialEq)]
struct SchedulerCallData {
when: DispatchTime<BlockNumberFor<Runtime>>,
call: BoundedCallOf<Runtime>,
}

impl ScheduleAnon<BlockNumberFor<Runtime>, CallOf<Runtime>, OriginFor<Runtime>> for MockScheduler {
type Address = ();

fn schedule(
when: DispatchTime<BlockNumberFor<Runtime>>,
_maybe_periodic: Option<Period<BlockNumberFor<Runtime>>>,
_priority: Priority,
_origin: OriginFor<Runtime>,
call: BoundedCallOf<Runtime>,
) -> Result<Self::Address, DispatchError> {
SCHEDULER_CALL_DATA
.with(|values| values.borrow_mut().push(SchedulerCallData { when, call }));

SCHEDULER_RETURN_VALUE
.with(|value| *value.borrow())
.expect("no return value configured for scheduler mock")
}

fn cancel(_address: Self::Address) -> Result<(), DispatchError> {
unimplemented!();
}

fn reschedule(
_address: Self::Address,
_when: DispatchTime<BlockNumberFor<Runtime>>,
) -> Result<Self::Address, DispatchError> {
unimplemented!();
}

fn next_dispatch_time(
_address: Self::Address,
) -> Result<BlockNumberFor<Runtime>, DispatchError> {
unimplemented!();
}
}

thread_local! {
pub static SCHEDULER_CALL_DATA: RefCell<Vec<SchedulerCallData>> =
const { RefCell::new(vec![]) };
pub static SCHEDULER_RETURN_VALUE: RefCell<Option<DispatchResult>> =
const { RefCell::new(None) };
}

0 comments on commit 26d5b8a

Please sign in to comment.