#![cfg_attr(not(feature = "std"), no_std)]
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use serde::{Deserialize, Serialize};
pub use sp_consensus_aura::sr25519::AuthorityId as AuraId;
pub use sp_staking::{SessionIndex, EraIndex,};
pub use sp_runtime::{
generic, BoundedVec,
};
use sp_core::crypto::KeyTypeId;
use sp_std::vec::Vec;
pub const KEY_TYPE: KeyTypeId = KeyTypeId(*b"phro");
pub const PHRON_ENGINE_ID: sp_runtime::ConsensusEngineId = *b"FRNK";
pub const DEFAULT_FINALITY_VERSION: Version = 0;
pub const CURRENT_FINALITY_VERSION: u16 = LEGACY_FINALITY_VERSION + 1;
pub const LEGACY_FINALITY_VERSION: u16 = 1;
#[cfg(feature = "short_session")]
pub const DEFAULT_SESSION_PERIOD: u32 = 30;
#[cfg(feature = "short_session")]
pub const DEFAULT_SESSIONS_PER_ERA: u32 = 3;
#[cfg(not(feature = "short_session"))]
pub const DEFAULT_SESSION_PERIOD: u32 = 900;
#[cfg(not(feature = "short_session"))]
pub const DEFAULT_SESSIONS_PER_ERA: u32 = 8;
pub const MILLISECS_PER_BLOCK: u64 = 1000;
pub const MAX_BLOCK_SIZE: u32 = 5 * 1024 * 1024;
pub const DEFAULT_UNIT_CREATION_DELAY: u64 = 300;
pub const LENIENT_THRESHOLD: sp_runtime::Perquintill = sp_runtime::Perquintill::from_percent(90);
pub const DEFAULT_BAN_MINIMAL_EXPECTED_PERFORMANCE: sp_runtime::Perbill = sp_runtime::Perbill::from_percent(0);
pub const DEFAULT_BAN_SESSION_COUNT_THRESHOLD: SessionCount = 3;
pub const DEFAULT_BAN_REASON_LENGTH: u32 = 300;
pub const DEFAULT_MAX_WINNERS: u32 = u32::MAX;
pub const DEFAULT_COMMITTEE_SIZE: u32 = 4;
pub const DEFAULT_CLEAN_SESSION_COUNTER_DELAY: SessionCount = 960;
pub const DEFAULT_BAN_PERIOD: EraIndex = 10;
mod app {
use sp_application_crypto::{app_crypto, ed25519};
app_crypto!(ed25519, crate::KEY_TYPE);
}
sp_application_crypto::with_pair! {
pub type AuthorityPair = app::Pair;
}
pub type AuthorityId = app::Public;
pub type AuthoritySignature = app::Signature;
pub type Version = u32;
pub type BlockNumber = u32;
pub type Signature = account::EthereumSignature;
pub type AccountId = <<Signature as sp_runtime::traits::Verify>::Signer as sp_runtime::traits::IdentifyAccount>::AccountId;
pub type Balance = u128;
pub type Nonce = u32;
pub type TransactionPriority = u64;
pub type Index = u32;
pub type SessionCount = u32;
pub type BlockCount = u32;
pub type Hash = sp_core::H256;
pub type Header = sp_runtime::generic::Header<BlockNumber, sp_runtime::traits::BlakeTwo256>;
pub type Block = sp_runtime::generic::Block<Header, sp_runtime::OpaqueExtrinsic>;
pub type BlockHash = <Header as sp_runtime::traits::Header>::Hash;
#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
pub struct VersionChange {
pub version_incoming: Version,
pub session: SessionIndex,
}
pub trait FinalityCommitteeManager<T> {
fn on_next_session_finality_committee(committee: Vec<T>);
}
pub trait SessionInfoProvider<T> {
fn current_session() -> SessionIndex;
fn next_session_block_number(current_block: T) -> Option<T>;
}
#[derive(Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
pub enum ApiError {
DecodeKey
}
#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
pub struct SessionAuthorityData {
authorities: Vec<AuthorityId>,
emergency_finalizer: Option<AuthorityId>,
}
impl SessionAuthorityData {
pub fn new(authorities: Vec<AuthorityId>, emergency_finalizer: Option<AuthorityId>) -> Self {
Self {
authorities,
emergency_finalizer,
}
}
pub fn authorities(&self) -> &Vec<AuthorityId> {
&self.authorities
}
pub fn emergency_finalizer(&self) -> &Option<AuthorityId> {
&self.emergency_finalizer
}
}
#[derive(Clone, Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
pub struct SessionCommittee<T> {
pub finality_committee: Vec<T>,
pub block_producers: Vec<T>,
}
#[derive(Eq, PartialEq, Debug, Encode, Decode, TypeInfo)]
pub enum SessionValidatorError {
SessionNotWithinRange {
lower_limit: SessionIndex,
upper_limit: SessionIndex,
},
Other(Vec<u8>),
}
sp_api::decl_runtime_apis! {
pub trait PhronSessionApi {
fn next_session_authorities() -> Result<Vec<AuthorityId>, ApiError>;
fn authorities() -> Vec<AuthorityId>;
fn next_session_authority_data() -> Result<SessionAuthorityData, ApiError>;
fn authority_data() -> SessionAuthorityData;
fn session_period() -> u32;
fn millisecs_per_block() -> u64;
fn finality_version() -> Version;
fn next_session_finality_version() -> Version;
fn next_session_aura_authorities() -> Vec<AuraId>;
fn key_owner(key: AuthorityId) -> Option<AccountId>;
}
}
#[derive(Decode, Encode, TypeInfo, Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct BanConfig {
pub minimal_expected_performance: sp_runtime::Perbill,
pub underperformed_session_count_threshold: SessionCount,
pub clean_session_counter_delay: SessionCount,
pub ban_period: EraIndex,
}
impl Default for BanConfig {
fn default() -> Self {
BanConfig {
minimal_expected_performance: DEFAULT_BAN_MINIMAL_EXPECTED_PERFORMANCE,
underperformed_session_count_threshold: DEFAULT_BAN_SESSION_COUNT_THRESHOLD,
clean_session_counter_delay: DEFAULT_CLEAN_SESSION_COUNTER_DELAY,
ban_period: DEFAULT_BAN_PERIOD,
}
}
}
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug)]
pub enum BanReason {
InsufficientUptime(u32),
OtherReason(BoundedVec<u8, sp_runtime::traits::ConstU32<DEFAULT_BAN_REASON_LENGTH>>),
}
#[derive(PartialEq, Eq, Clone, Encode, Decode, TypeInfo, Debug)]
pub struct BanInfo {
pub reason: BanReason,
pub start: EraIndex,
}
#[derive(Eq, PartialEq, Decode, Encode, TypeInfo)]
pub struct EraValidators<AccountId> {
pub reserved: Vec<AccountId>,
pub non_reserved: Vec<AccountId>,
}
impl<AccountId> Default for EraValidators<AccountId> {
fn default() -> Self {
Self {
reserved: Vec::new(),
non_reserved: Vec::new(),
}
}
}
pub trait BanHandler {
type AccountId;
fn can_ban(who: &Self::AccountId) -> bool;
}
pub trait ValidatorProvider {
type AccountId;
fn current_era_validators() -> EraValidators<Self::AccountId>;
fn current_era_committee_size() -> CommitteeSeats;
}
#[derive(Decode, Encode, TypeInfo, Clone, Serialize, Deserialize)]
pub struct SessionValidators<T> {
pub committee: Vec<T>,
pub non_committee: Vec<T>,
}
impl<T> Default for SessionValidators<T> {
fn default() -> Self {
Self {
committee: Vec::new(),
non_committee: Vec::new(),
}
}
}
#[derive(Decode, Encode, TypeInfo, Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct CommitteeSeats {
pub reserved_seats: u32,
pub non_reserved_seats: u32,
pub non_reserved_finality_seats: u32,
}
impl CommitteeSeats {
pub fn size(&self) -> u32 {
self.reserved_seats.saturating_add(self.non_reserved_seats)
}
}
impl Default for CommitteeSeats {
fn default() -> Self {
CommitteeSeats {
reserved_seats: DEFAULT_COMMITTEE_SIZE,
non_reserved_seats: 0,
non_reserved_finality_seats: 0,
}
}
}
pub trait BannedValidators {
type AccountId;
fn banned() -> Vec<Self::AccountId>;
}
pub trait EraManager {
fn on_new_era(era: EraIndex);
}
#[derive(Decode, Encode, TypeInfo, Debug, Clone, PartialEq, Eq)]
pub enum ElectionOpenness {
Permissioned,
Permissionless,
}