#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
extern crate alloc;
#[cfg(not(feature = "std"))]
use alloc::string::String;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
pub use fp_account::AccountId20;
use frame_support::dispatch::DispatchClass;
use frame_support::weights::constants::{BlockExecutionWeight, ExtrinsicBaseWeight};
use frame_system::limits::{BlockLength, BlockWeights};
use parity_scale_codec::{Decode, Encode};
use scale_info::TypeInfo;
use serde::{Deserialize, Serialize};
use sp_runtime::generic::UncheckedExtrinsic;
use sp_runtime::traits::{Convert, IdentifyAccount, Verify};
use sp_runtime::transaction_validity::TransactionValidityError;
use sp_runtime::{MultiAddress, MultiSignature, Perbill};
use sp_weights::constants::WEIGHT_REF_TIME_PER_SECOND;
use sp_weights::Weight;
use subspace_runtime_primitives::{MAX_BLOCK_LENGTH, SHANNON, SLOT_PROBABILITY};
pub type Signature = MultiSignature;
pub type AccountId = <<Signature as Verify>::Signer as IdentifyAccount>::AccountId;
pub type Balance = u128;
pub type Nonce = u32;
pub type Hash = sp_core::H256;
pub type BlockNumber = u32;
pub type Address = MultiAddress<AccountId, ()>;
pub const SLOT_DURATION: u64 = 1000;
pub type EVMChainId = u64;
pub const NORMAL_DISPATCH_RATIO: Perbill = Perbill::from_percent(65);
pub fn maximum_domain_block_weight() -> Weight {
let consensus_maximum_normal_block_length =
*maximum_block_length().max.get(DispatchClass::Normal) as u64;
let weight =
NORMAL_DISPATCH_RATIO * Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND.saturating_mul(2), 0);
weight.set_proof_size(consensus_maximum_normal_block_length)
}
pub const ERR_NONCE_OVERFLOW: u8 = 100;
pub const ERR_BALANCE_OVERFLOW: u8 = 200;
pub fn maximum_block_length() -> BlockLength {
BlockLength::max_with_normal_ratio(MAX_BLOCK_LENGTH, NORMAL_DISPATCH_RATIO)
}
pub const EXISTENTIAL_DEPOSIT: Balance = 500 * SHANNON;
const AVERAGE_ON_INITIALIZE_RATIO: Perbill = Perbill::from_percent(5);
pub fn calculate_max_bundle_weight(
max_domain_block_weight: Weight,
consensus_slot_probability: (u64, u64),
bundle_slot_probability: (u64, u64),
) -> Option<(u64, Weight)> {
let expected_bundles_per_block = bundle_slot_probability
.0
.checked_mul(consensus_slot_probability.1)?
.checked_div(
bundle_slot_probability
.1
.checked_mul(consensus_slot_probability.0)?,
)?;
let max_proof_size = max_domain_block_weight.proof_size();
let max_bundle_weight = max_domain_block_weight.checked_div(expected_bundles_per_block)?;
Some((
expected_bundles_per_block,
max_bundle_weight.set_proof_size(max_proof_size),
))
}
fn maximum_domain_extrinsic_weight() -> Option<Weight> {
let (_, max_bundle_weight) =
calculate_max_bundle_weight(maximum_domain_block_weight(), SLOT_PROBABILITY, (1, 1))?;
Some(max_bundle_weight)
}
pub fn block_weights() -> BlockWeights {
let maximum_block_weight = Weight::from_parts(u64::MAX, u64::MAX);
let max_extrinsic_weight =
maximum_domain_extrinsic_weight().expect("Maximum extrinsic weight must always be valid");
BlockWeights::builder()
.base_block(BlockExecutionWeight::get())
.for_class(DispatchClass::all(), |weights| {
weights.base_extrinsic = ExtrinsicBaseWeight::get();
weights.max_extrinsic = Some(max_extrinsic_weight);
weights.max_total = Some(maximum_block_weight);
})
.avg_block_initialization(AVERAGE_ON_INITIALIZE_RATIO)
.build_or_panic()
}
pub trait Signer<AccountId, Lookup> {
fn signer(&self, lookup: &Lookup) -> Option<AccountId>;
}
impl<Address, AccountId, Call, Signature, Extra, Lookup> Signer<AccountId, Lookup>
for UncheckedExtrinsic<Address, Call, Signature, Extra>
where
Address: Clone,
Extra: sp_runtime::traits::SignedExtension<AccountId = AccountId>,
Lookup: sp_runtime::traits::Lookup<Source = Address, Target = AccountId>,
{
fn signer(&self, lookup: &Lookup) -> Option<AccountId> {
self.signature
.as_ref()
.and_then(|(signed, _, _)| lookup.lookup(signed.clone()).ok())
}
}
#[derive(
Debug, Encode, Decode, Clone, Eq, PartialEq, TypeInfo, Serialize, Deserialize, Ord, PartialOrd,
)]
pub enum MultiAccountId {
AccountId32([u8; 32]),
AccountId20([u8; 20]),
Raw(Vec<u8>),
}
pub trait TryConvertBack<A, B>: Convert<A, B> {
fn try_convert_back(b: B) -> Option<A>;
}
pub struct AccountIdConverter;
impl Convert<AccountId, MultiAccountId> for AccountIdConverter {
fn convert(account_id: AccountId) -> MultiAccountId {
MultiAccountId::AccountId32(account_id.into())
}
}
impl TryConvertBack<AccountId, MultiAccountId> for AccountIdConverter {
fn try_convert_back(multi_account_id: MultiAccountId) -> Option<AccountId> {
match multi_account_id {
MultiAccountId::AccountId32(acc) => Some(AccountId::new(acc)),
_ => None,
}
}
}
pub struct AccountId20Converter;
impl Convert<AccountId20, MultiAccountId> for AccountId20Converter {
fn convert(account_id: AccountId20) -> MultiAccountId {
MultiAccountId::AccountId20(account_id.into())
}
}
impl TryConvertBack<AccountId20, MultiAccountId> for AccountId20Converter {
fn try_convert_back(multi_account_id: MultiAccountId) -> Option<AccountId20> {
match multi_account_id {
MultiAccountId::AccountId20(acc) => Some(AccountId20::from(acc)),
_ => None,
}
}
}
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub struct CheckExtrinsicsValidityError {
pub extrinsic_index: u32,
pub transaction_validity_error: TransactionValidityError,
}
#[derive(Debug, Decode, Encode, TypeInfo, PartialEq, Eq, Clone)]
pub struct DecodeExtrinsicError(pub String);
pub const CHECK_EXTRINSICS_AND_DO_PRE_DISPATCH_METHOD_NAME: &str =
"DomainCoreApi_check_extrinsics_and_do_pre_dispatch";
pub mod opaque {
use crate::BlockNumber;
#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
use sp_runtime::generic;
use sp_runtime::traits::BlakeTwo256;
pub use sp_runtime::OpaqueExtrinsic as UncheckedExtrinsic;
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
pub type BlockId = generic::BlockId<Block>;
pub type AccountId = Vec<u8>;
}
#[cfg(test)]
mod test {
use super::block_weights;
#[test]
fn test_block_weights() {
let _block_weights = block_weights();
}
}