pallet_time_release/types.rs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
//! Types for the TimeRelease Pallet
#![cfg_attr(not(feature = "std"), no_std)]
use parity_scale_codec::{Decode, DecodeWithMemTracking, Encode, HasCompact, MaxEncodedLen};
use sp_runtime::{traits::AtLeast32Bit, DispatchError, RuntimeDebug};
extern crate alloc;
use alloc::boxed::Box;
use core::cmp::{Eq, PartialEq};
use scale_info::TypeInfo;
/// Alias for a schedule identifier
pub type ScheduleName = [u8; 32];
/// The release schedule.
///
/// Benefits would be granted gradually, `per_period` amount every `period`
/// of blocks after `start`.
#[derive(
Clone,
Encode,
Decode,
DecodeWithMemTracking,
PartialEq,
Eq,
RuntimeDebug,
MaxEncodedLen,
TypeInfo,
)]
pub struct ReleaseSchedule<BlockNumber, Balance>
where
Balance: MaxEncodedLen + HasCompact,
{
/// Vesting starting block
pub start: BlockNumber,
/// Number of blocks between vest
pub period: BlockNumber,
/// Number of vest
pub period_count: u32,
/// Amount of tokens to release per vest
#[codec(compact)]
pub per_period: Balance,
}
impl<BlockNumber: AtLeast32Bit + Copy, Balance: AtLeast32Bit + MaxEncodedLen + Copy>
ReleaseSchedule<BlockNumber, Balance>
{
/// Returns the end of all periods, `None` if calculation overflows.
pub fn end(&self) -> Option<BlockNumber> {
// period * period_count + start
self.period.checked_mul(&self.period_count.into())?.checked_add(&self.start)
}
/// Returns all frozen amount, `None` if calculation overflows.
pub fn total_amount(&self) -> Option<Balance> {
self.per_period.checked_mul(&self.period_count.into())
}
/// Returns frozen amount for a given `time`.
///
/// Note this func assumes schedule is a valid one(non-zero period and
/// non-overflow total amount), and it should be guaranteed by callers.
#[allow(clippy::expect_used)]
pub fn frozen_amount(&self, time: BlockNumber) -> Balance {
// full = (time - start) / period
// unrealized = period_count - full
// per_period * unrealized
let full = time
.saturating_sub(self.start)
.checked_div(&self.period)
.expect("ensured non-zero period; qed");
let unrealized = self.period_count.saturating_sub(full.unique_saturated_into());
self.per_period
.checked_mul(&unrealized.into())
.expect("ensured non-overflow total amount; qed")
}
}
/// A trait that defines a scheduler provider for scheduling calls to be executed at a specific block number.
pub trait SchedulerProviderTrait<Origin, BlockNumber, Call> {
/// Schedules a call to be executed at a specified block number.
///
/// # Returns
/// - `Ok(())` if the call was successfully scheduled.
/// - `Err(DispatchError)` if there was an error scheduling the call.
///
/// # Errors
/// This function may return a `DispatchError` for various reasons, such as:
/// - Insufficient permissions or invalid origin.
/// - Invalid block number or scheduling conflicts.
/// - Other runtime-specific errors.
fn schedule(
origin: Origin,
id: ScheduleName,
when: BlockNumber,
call: Box<Call>,
) -> Result<(), DispatchError>;
/// Cancels a scheduled call with an specific schedule-name.
///
/// # Returns
/// - `Ok(())` if the call was successfully canceled.
/// - `Err(DispatchError)` if there was an error canceling the call.
fn cancel(origin: Origin, id: ScheduleName) -> Result<(), DispatchError>;
}