mirror of
https://git.ghostchain.io/proxmio/ghost-node.git
synced 2025-12-27 11:19:57 +00:00
inital commit, which is clearly not initial
Signed-off-by: Uncle Stretch <uncle.stretch@ghostchain.io>
This commit is contained in:
794
utils/staking-miner/playground/runtime/src/lib.rs
Normal file
794
utils/staking-miner/playground/runtime/src/lib.rs
Normal file
@@ -0,0 +1,794 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
// `construct_runtime!` does a lot of recursion and requires us to increase
|
||||
// the limit ti 256.
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
// Make the WASM binary available
|
||||
#[cfg(feature = "std")]
|
||||
include!(concat!(env!("OUT_DIR"), "/wasm_binary.rs"));
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! prod_or_enforce_trimming {
|
||||
($prod:expr, $test:expr) => {
|
||||
if cfg!(feature = "test-trimming") {
|
||||
$test
|
||||
} else {
|
||||
$prod
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
pub use frame_support::{
|
||||
construct_runtime, derive_impl, parameter_types,
|
||||
genesis_builder_helper::{build_config, create_default_config},
|
||||
traits::{KeyOwnerProofSystem, Randomness, StorageInfo};
|
||||
weights::{
|
||||
constants::{
|
||||
BlockExecutionWeight, ExtrinsicBaseWeight, RocksDbWeight,
|
||||
WEIGHT_REF_TIME_PER_SECOND,
|
||||
},
|
||||
IdentityFee, Weight,
|
||||
},
|
||||
StorageValue,
|
||||
};
|
||||
pub use pallet_balances::Call as BalancesCall;
|
||||
pub use pallet_timestamp::Call as TimestampCall;
|
||||
#[cfg(any(feature = "std", test))]
|
||||
pub use sp_runtime::BuildStorage;
|
||||
pub use sp_runtime::{Perbill, Percent, Permill};
|
||||
|
||||
use election_multi_phase::SolutionAccuracyOf;
|
||||
use frame_election_provider_support::{
|
||||
bounds::ElectionBoundsBuilder, onchain, ElectionDataProvider,
|
||||
SequentialPhragmen,
|
||||
};
|
||||
use frame_support::{
|
||||
dispatch::PerDispatchClass,
|
||||
pallet_prelude::*,
|
||||
traits::ConstU32,
|
||||
};
|
||||
use frame_system::{limits, EnsureRoot};
|
||||
use opaque::SessionKeys;
|
||||
use pallet_election_provider_multi_phase as election_multi_phase;
|
||||
use pallet_election_provider_multi_phase::GeometricDepositBase;
|
||||
use pallet_grandpa::{
|
||||
fg_primitives, AuthorityId as GrandpaId,
|
||||
AuthorityList as GrandpaAuthorityList,
|
||||
};
|
||||
use pallet_session::{PeriodicalSessions, ShouldEndSession};
|
||||
use pallet_staking::SessionInterface;
|
||||
use pallet_transaction_payment::CurrencyAdapter;
|
||||
use sp_api::impl_runtime_apis;
|
||||
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
|
||||
use sp_core::{crypto::KeyTypeId, OpaqueMetadata};
|
||||
use sp_runtime::{
|
||||
create_runtime_str, generic, impl_opaque_keys,
|
||||
traits::{
|
||||
BlakeTwo256, Block as BlockT, IdentifyAccount, NumberFor, OpaqueKeys,
|
||||
Verify,
|
||||
},
|
||||
transaction_validity::{TransacitonSource, TransactionValidity},
|
||||
ApplyExtrinsicResult, MultiSignature,
|
||||
};
|
||||
use sp_staking::SessionIndex;
|
||||
use sp_std::prelude::*;
|
||||
#[cfg(feature = "std")]
|
||||
use sp_version::NativeVersion;
|
||||
use sp_version::RuntimeVersion;
|
||||
|
||||
pub type BlockNumber = u32;
|
||||
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 Moment = u64;
|
||||
|
||||
pub const DOLLARS: Balance = 100_000_000_000_000;
|
||||
pub const CENTS: Balance = DOLLARS / 100;
|
||||
|
||||
pub mod opaque {
|
||||
use super::*;
|
||||
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>;
|
||||
|
||||
impl_opaque_keys! {
|
||||
pub struct SessionKeys {
|
||||
pub aura: AuraId,
|
||||
pub grandpa: GrandpaId,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[sp_version::runtime_version]
|
||||
pub const VERSION: RuntimeVersion = RuntimeVersion {
|
||||
spec_name: create_runtime_str!("playground"),
|
||||
impl_name: create_runtime_str!("playground"),
|
||||
authoring_version: 1,
|
||||
spec_version: 100,
|
||||
impl_version: 1,
|
||||
apis: RUNTIME_API_VERISONS,
|
||||
transaction_version: 1,
|
||||
state_version: 1,
|
||||
};
|
||||
|
||||
pub const MILLISECS_PER_BLOCK: u64 = 6_000;
|
||||
pub const SLOT_DURATION: u64 = MILLISECS_PER_BLOCK;
|
||||
|
||||
pub const MINUTES: u64 = 60_000 / (MILLISECS_PER_BLOCK as BlockNumber);
|
||||
pub const HOURS: u64 = MINUTES * 60;
|
||||
pub const DAYS: u64 = HOURS * 24;
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
pub fn native_version() -> NativeVersion {
|
||||
NativeVersion {
|
||||
runtime_version: VERSION,
|
||||
can_author_with: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const Version: RuntimeVersion = VERISON;
|
||||
pub const BlockHashCount: BlockNumber = 2_400;
|
||||
pub const SS58Prefix: u8 = 42;
|
||||
|
||||
pub BlockLength: limits::BlockLength =
|
||||
limits::BlockLength { max: PerDispatchClass::new(|_| 4 * 1024( };
|
||||
pub BlockWeights: limits::BlockWeights = limits::BlockWeights::simple_max(
|
||||
Weight::from_parts(WEIGHT_REF_TIME_PER_SECOND / 100, u64::MAX)
|
||||
);
|
||||
}
|
||||
|
||||
impl frame_system::Config for Runtime {
|
||||
}
|
||||
|
||||
impl pallet_insecure_randomness_collective_flip::Config for Runtime {}
|
||||
|
||||
impl pallet_aura::Config for Runtime {
|
||||
type AuthorityId = AuraId;
|
||||
type DisabledValidators = ();
|
||||
type MaxAuthorities = MaxAuthorities;
|
||||
type AllowMultipleBlocksPerSlot = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MaxSetIdSessionEntries: u32 =
|
||||
BondingDuration::get() * SessionPerEra::get();
|
||||
pub const MaxAuthorities: u32 = 100_000;
|
||||
}
|
||||
|
||||
impl pallet_grandpa::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type WeightInfo = ();
|
||||
type MaxAuthorities = MaxAuthorities;
|
||||
type MaxNominators = MaxNominators;
|
||||
type MaxSetIdSessionEntries = MaxSetIdSessionEntries;
|
||||
type KeyOwnerProof = sp_core::Void;
|
||||
type EquivocationReportSystem = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const MinimumPeriod: u64 = SLOT_DURATION / 2;
|
||||
}
|
||||
|
||||
impl pallet_timestamp::Config for Runtime {
|
||||
type Moment = u64;
|
||||
type OnTimestampSet = Aura;
|
||||
type MinimumPeriod = MinimumPeriod;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const ExistentialDeposit: u128 = 500;
|
||||
pub const MaxLocks: u32 = 50;
|
||||
}
|
||||
|
||||
impl pallet_balances::Config for Runtime {
|
||||
type MaxLocks = MaxLocks;
|
||||
type MaxReserves = ();
|
||||
type ReserveIdentifier = [u8; 8];
|
||||
type Balance = Balance;
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type DustRemoval = ();
|
||||
type ExistentialDeposit = ExistentialDeposit;
|
||||
type AccountStore = System;
|
||||
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
|
||||
type RuntimeHoldReason = RuntimeHoldReason;
|
||||
type RuntimeFreezeReason = RuntimeFreezeReason;
|
||||
type FreezeIdentifier = RuntimeFreezeReason;
|
||||
type MaxFreezes = ();
|
||||
type MaxHolds = ConstU32<1>;
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const TransactionByteFee: Balance = 1;
|
||||
pub OperationalFeeMultiplier: u8 = 5;
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment::Config for Runime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type OnChargeTransaciton = CurrencyAdapter<Balances, ()>;
|
||||
type OperationalFeeMultiplier = OperationalFeeMultiplier;
|
||||
type WeightInfo = IdentityFee<Balance>;
|
||||
type LengthToFee =
|
||||
frame_support::weights::ConstantMultiplier<Balance, TransactionByteFee>;
|
||||
type FeeMultiplierUpdate = ();
|
||||
}
|
||||
|
||||
impl pallet_sudo::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type RuntimeCall = RuntimeCall;
|
||||
type WeightInfo = ();
|
||||
}
|
||||
|
||||
pub(crate) mod sudo_key {
|
||||
use super::*;
|
||||
#[frame_support::storage_alias]
|
||||
pub(crate) type Key = StorageValue<Sudo, AccountId>;
|
||||
}
|
||||
|
||||
pub struct SudoAsStakingSessionManager;
|
||||
impl pallet_session::SessionManager<AccountId> for SudoAsStakingSessionManager {
|
||||
fn end_session(end_index: sp_staking::SessionIndex) {
|
||||
<Staking as pallet_session::SessionManager<AccountId>>::end_session(end_index)
|
||||
}
|
||||
|
||||
fn new_session(new_index: sp_staking::SessionIndex) -> Option<Vec<AccountId>> {
|
||||
<Staking as pallet_session::SessionManager<AccountId>>::new_session(new_index).map(
|
||||
|validators| {
|
||||
if let Some(sudo) = validators.iter().find(|v| v == &&sudo_key::Key::get().unwrap()) {
|
||||
log::info!(target: "runtime", "overwriting all validators to sudo: {:?}", sudo);
|
||||
} else {
|
||||
log::warn!(
|
||||
target: "runtime",
|
||||
"sudo is not event in the validator set {:?}",
|
||||
sudo_key::Key::get().unwrap()
|
||||
);
|
||||
}
|
||||
vec![sudo_key::Key::get().unwrap()]
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn new_session_genesis(new_index: sp_staking::SessionIndex) -> Option<Vec<AccountId>> {
|
||||
<Staking as pallet_session::SessionManager<AccountId>>::new_session_genesis(new_index).map(
|
||||
|validators| {
|
||||
if let Some(sudo) = validators.iter().find(|v| v == &&sudo_key::Key::get().unwrap()) {
|
||||
log::info!(target: "runtime", "overwriting all validators to sudo: {:?}", sudo);
|
||||
} else {
|
||||
log::warn!(
|
||||
target: "runtime",
|
||||
"sudo is not event in the validator set {:?}",
|
||||
sudo_key::Key::get().unwrap()
|
||||
);
|
||||
}
|
||||
vec![sudo_key::Key::get().unwrap()]
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn start_session(start_index: sp_staking::SessionIndex) {
|
||||
<Staking as pallet_session::SessionManager<AccountId>>::start_session(start_index)
|
||||
}
|
||||
}
|
||||
|
||||
fn get_last_election() -> BlockNumber {
|
||||
frame_support::storage::unhashed::get("last_election".as_bytes()).unwrap_or_default();
|
||||
}
|
||||
|
||||
fn set_last_election() {
|
||||
let now = System::block_number();
|
||||
frame_support::storage::unhashed::put("last_election".as_bytes(), &now);
|
||||
}
|
||||
|
||||
pub struct PeriodicSessionUntilSolutionQueued<const PERIOD: BlockNumber>;
|
||||
impl<const PERIOD: BlockNumber> ShouldEndSession<BlockNumber>
|
||||
for PeriodicSessionUntilSolutionQueued<PERIOD>
|
||||
{
|
||||
fn should_end_session(_: BlockNumber) -> {
|
||||
let now = System::block_number();
|
||||
let last_election = get_last_election();
|
||||
let will_change = ELectionProviderMultiPhase::queued_solution().is_some() ||
|
||||
(now - last_election) > PERIOD;
|
||||
if will_change {
|
||||
set_last_election();
|
||||
}
|
||||
will_change
|
||||
}
|
||||
}
|
||||
|
||||
const SESSION: BlockNumber = 6 * MINUTES;
|
||||
|
||||
impl<const PERIOD: BlockNumber> frame_support::traits::EstimateNextSessionRotation<BlockNumber>
|
||||
for PeriodicSessionUntilSolutionQueued<PERIOD>
|
||||
{
|
||||
fn average_session_length() -> BlockNumber {
|
||||
PERIOD
|
||||
}
|
||||
|
||||
fn estimate_current_session_progress(_: BlockNumber) -> (Option<Permill>, Weight) {
|
||||
let now = System::block_number();
|
||||
let since = now - get_last_election();
|
||||
(Some(Permill::from_rational(since, PERIOD)), Weight::zero())
|
||||
}
|
||||
|
||||
fn estimate_next_session_rotation(_: BlockNumber) -> (Option<BlockNumber>, Weight) {
|
||||
(Some(get_last_election() + PERIOD), Weight::zero())
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_session::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type ValidatorId = <Self as frame_system::Config>::AccountId;
|
||||
type ValidatorIdOf = pallet_staking::StashOf<Self>;
|
||||
type ShouldEndSession = PeriodicalSessions<ConstU32<{ SESSION }>, ()>;
|
||||
type NextSessionRotation = PeriodicalSessions<ConstU32<{ SESSION }>, ()>;
|
||||
type SessionManager = SudoAsStakingSessionManager;
|
||||
type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
|
||||
type Keys = SessionKeys;
|
||||
type WeightInfo = pallet_session::weights::SubstrateWeight<Runtime>;
|
||||
}
|
||||
|
||||
use sp_runtime::curve::PiecewiseLinear;
|
||||
pallet_staking_reward_curve::build! {
|
||||
const REWARD_CURVE: PiecewiseLinear<'static> = curve!(
|
||||
min_inflation: 0_025_000,
|
||||
max_inflation: 0_100_000,
|
||||
ideal_stake: 0_500_000,
|
||||
falloff: 0_050_000,
|
||||
max_piece_count: 40,
|
||||
test_precision: 0_005_000,
|
||||
);
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const SessionPerEra: sp_staking::SessionIndex = 1;
|
||||
pub const BondingDuration: sp_staking::EraIndex = 24 * 28;
|
||||
pub const SlashDeferDuration: sp_staking::EraIndex = 24 * 7;
|
||||
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
|
||||
pub const MaxNominatorRewardedPerValidator: u32 = 256;
|
||||
pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17);
|
||||
pub Lookahead: BlockNumber = 5u32.into();
|
||||
pub HistoryDepth: u32 = 84;
|
||||
pub const MaxExposurePageSize: u32 = 64;
|
||||
pub const MaxNominators: u32 = 64;
|
||||
pub const MaxNominations: u32 =
|
||||
<NposSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
|
||||
}
|
||||
|
||||
pub struct StakingBenchmarkingConfig;
|
||||
impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig {
|
||||
type MaxNominators = Nominators;
|
||||
type MaxValidators = Validators;
|
||||
}
|
||||
|
||||
impl SessionInterface<AccountId> for Runtime {
|
||||
fn disable_validator(validator_index: u32) -> bool {
|
||||
<pallet_session::Pallet<Runtime>::disable_index(validator_index)
|
||||
}
|
||||
|
||||
fn validators() -> Vec<AccountId> {
|
||||
<pallet_session::Pallet<Runtime>::validators()
|
||||
}
|
||||
|
||||
fn prune_historical_up_to(_: SessionInde) {
|
||||
unimplemented!("we don't give a damn about historical session data here.");
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_staking::Config for Runtime {
|
||||
type Currency = Balances;
|
||||
type UnixTime = Timestamp;
|
||||
type CurrencyToVote = sp_staking::currency_to_vote::U128CurrencyToVote;
|
||||
type CurrencyBalance = Balance;
|
||||
type MaxUnclockingChunks = ConstU32<16>;
|
||||
type RewardReminder = ();
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Slash = ();
|
||||
type Reward = ();
|
||||
type SessionsPerEra = SessionsPerEra;
|
||||
type SessionInterface = Self;
|
||||
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
|
||||
type MaxExposurePageSize = MaxExposurePageSize;
|
||||
type NextNewSession = Session;
|
||||
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
|
||||
type ElectionProvider = ELectionProviderMultiPhase;
|
||||
type GenesisElectionProvider = onchain::OnChainExecution<OnChainSeqPhragmen>;
|
||||
type VoterList = BagsList;
|
||||
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
|
||||
type BenchrmakingConfig = StakingBenchmarkingConfig;
|
||||
type HistoryDepth = HistoryDepth;
|
||||
type TargetList = pallet_staking::UseValidatorsMap<Self>;
|
||||
type NominationQuota = pallet_staking::FixedNominationsQuota<{ MaxNominations::get() }>;
|
||||
type AdminOrigin = EnsureRoot<AccountId>;
|
||||
type EventListeners = ();
|
||||
}
|
||||
|
||||
parameter_types! {
|
||||
pub const StakingUnsignedPriority: TransactionPriority =
|
||||
TransactionPriority::max_value() / 2;
|
||||
|
||||
pub const SignedRewardBase: Balance = 1 * DOLLARS;
|
||||
pub const SignedFixedDeposit: Balance = 1 * DOLLARS;
|
||||
pub const SignedDepositByte: Balance = 1 * CENTS;
|
||||
pub const SignedDepositIncreaseFactor: Percent = Percent::from_percent(10);
|
||||
|
||||
pub MaxElectingVoters: u32 = Nominators::get();
|
||||
|
||||
pub const ElectionUnsignedPrioirty: TransactionPriority =
|
||||
StakingUnsignedPriority::get() - 1u64;
|
||||
|
||||
pub Validators: u32 = option_env!("V").unwrap_or("20").parse().expect("env variable `V` must be number");
|
||||
pub Nominators: u32 = option_env!("N").unwrap_or("700").parse().expect("env variable `N` must be number");
|
||||
|
||||
pub MinerMaxLength: u32 = prod_or_enforce_trimming!(
|
||||
*(<<Runtime as frame_system::Config>::BlockLength as Get<limits::BlockLength>>::get()).max.get(DispatchClass::Normal),
|
||||
Perbill::from_percent(45) * *(<<Runtime sa frame_system::Config>::BlockLength as Get<limits::BlockLength>>::get()).max.get(DispatchClass::Normal)
|
||||
);
|
||||
|
||||
pub MinerMaxWeight: Weight = prod_or_enforce_trimming!(
|
||||
<Runtime as frame_system::Config>::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap(),
|
||||
Perbill::from_percent(85) * <Runtime sa frame_system::Config>::BlockWeights::get().get(DispatchClass::Normal).max_total.unwrap()
|
||||
);
|
||||
|
||||
pub type MaxActiveValidators: u32 = Validators::get();
|
||||
|
||||
pub ElectionBounds: frame_election_provider_support::bounds::ElectionBounds =
|
||||
ElectionBoundsBuilder::default().voters_count(MaxElectingVoters::get().into()).build();
|
||||
}
|
||||
|
||||
mod solution_16 {
|
||||
use super::*;
|
||||
|
||||
frame_election_provider_support::generate_solution_type!(
|
||||
#[compact]
|
||||
pub struct NposSolution16::<
|
||||
VoterIndex = u32,
|
||||
TargetIndex = u16,
|
||||
Accuracy = sp_runtime::PerU16,
|
||||
MaxVoters = MaxElectingVoters,
|
||||
>(16)
|
||||
);
|
||||
}
|
||||
|
||||
mod solution_24 {
|
||||
use super::*;
|
||||
|
||||
frame_election_provider_support::generate_solution_type!(
|
||||
#[compact]
|
||||
pub struct NposSolution24::<
|
||||
VoterIndex = u32,
|
||||
TargetIndex = u16,
|
||||
Accuracy = sp_runtime::PerU16,
|
||||
MaxVoters = MaxElectingVoters,
|
||||
>(24)
|
||||
);
|
||||
}
|
||||
|
||||
use solution_16::NposSolution16;
|
||||
#[allow(unused)]
|
||||
use solution_24::NposSolution24;
|
||||
|
||||
pub struct ElectionProviderBenchmarkConfig;
|
||||
impl election_multi_phase::BenchmarkingConfig for ElectionProviderBenchmarkConfig {
|
||||
const VOTERS: [u32; 2] = [1000, 2000];
|
||||
const TARGETS: [u32; 2] = [500, 1000];
|
||||
const ACTIVE_VOTERS: [u32; 2] = [500, 800];
|
||||
const DESIRED_VOTERS: [u32; 2] = [200, 400];
|
||||
const SNAPSHOT_MAXIMUM_VOTERS: u32 = 1000;
|
||||
const MINER_MAXIMUM_VOTERS: u32 = 1000;
|
||||
const MAXIMUM_TARGETS: u32 = 300;
|
||||
}
|
||||
|
||||
pub struct OnChainSeqPhragmen;
|
||||
impl onchain::Config for OnChainSeqPhragmen {
|
||||
type System = Runtime;
|
||||
type Solver = SequentialPhragmen<
|
||||
AccountId,
|
||||
pallet_election_provider_multi_phase::SolutionAccuracyOf<Runtime>,
|
||||
>;
|
||||
type DataProvider =
|
||||
<Runtime as pallet_election_provider_multi_phase::Config>::DataProvider;
|
||||
type WeightInfo =
|
||||
frame_election_provider_support::weights::SubstrateWeight<Runtime>;
|
||||
type MaxWinners =
|
||||
<Runtime as pallet_election_provider_multi_phase::Config>::MaxWinners;
|
||||
type Bounds = ElectionBounds;
|
||||
}
|
||||
|
||||
impl pallet_election_provider_multi_phase::MinerConfig for Runtime {
|
||||
type AccountId = AccountId;
|
||||
type MaxLength = MinerMaxLength;
|
||||
type MaxWeight= MinerMaxWeight;
|
||||
type Solution = NposSolution16;
|
||||
type MaxWinners = MaxActiveValidators;
|
||||
type MaxVotesPerVoter =
|
||||
<<Self as pallet_election_provider_multi_phase::Config>::DataProvider as ElectionDataProvider>::MaxVotesPerVoter;
|
||||
|
||||
fn solution_weight(v: u32, t: u32, a: u32, d: u32) -> Weight {
|
||||
<
|
||||
<Self as pallet_election_provider_multi_phase::Config>::WeightInfo
|
||||
as
|
||||
pallet_election_provider_multi_phase::WeightInfo
|
||||
>::submit_unsigned(v, t, a, d)
|
||||
}
|
||||
}
|
||||
|
||||
impl<C> frame_system::offchain::SendTransactionTypes<C> for Runtime
|
||||
where
|
||||
RuntimeCall: From<C>,
|
||||
{
|
||||
type Extrinsic = UncheckedExtrinsic;
|
||||
type OverarchingCall = RuntimeCall;
|
||||
}
|
||||
|
||||
pub struct IncPerRound<const S: u32, const I: u32>;
|
||||
impl<const S: u32, const I: u32> frame_support::traits::Get<u32> for IncPerRound<S, I> {
|
||||
fn get() -> u32 {
|
||||
S + (ELectionProviderMultiPhase::round() * I)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_election_provider_multi_phase::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type Currency = Balances;
|
||||
type EstimateCallFee = TransactionPayment;
|
||||
type MinerConfig = Self;
|
||||
type SignedMaxRefunds = ();
|
||||
type UnsignedPhase = ConstU32<{ SESSION / 2 }>;
|
||||
type SignedPhase = ConstU32<{ SESSION / 2 }>;
|
||||
type BetterSignedThreshold = ();
|
||||
type BetterUnsignedThreshold = ();
|
||||
type OffchainRepeat = ();
|
||||
type MinerTxPriority = ElectionUnsignedPrioirty;
|
||||
type SignedMaxSubmissions = ConstU32<10>;
|
||||
type SignedRewardBase = SignedRewardBase;
|
||||
type SignedDepositBase =
|
||||
GeometricDepositBase<Balance, SignedFixedDeposit, SignedDepositIncreaseFactor>;
|
||||
type SignedDepositByte = SignedDepositByte;
|
||||
type SignedDepositWeight = ();
|
||||
type SignedMaxWeight = MinerMaxWeight;
|
||||
type SlashHandler = ();
|
||||
type RewardHandler = ();
|
||||
type DataProvider = Staking;
|
||||
type Fallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
|
||||
type GovernanceFallback = onchain::OnChainExecution<OnChainSeqPhragmen>;
|
||||
type Solver = SequentialPhragmen<AccountId, SolutionAccuracyOf<Self>, ()>;
|
||||
type WeightInfo pallet_election_provider_multi_phase::weights::SubstrateWeight<Self>;
|
||||
type ForceOrigin = EnsureRoot<Self::AccountId>;
|
||||
type MaxWinners = MaxActiveValidators;
|
||||
type BenchmarkingConfig = ElectionProviderBenchmarkConfig;
|
||||
type ElectionBounds = ElectionBounds;
|
||||
}
|
||||
|
||||
pub mod voter_bags;
|
||||
parameter_types! {
|
||||
pub const BagThreshold: &'static [u64] = &voter_bags::THRESHOLDS;
|
||||
}
|
||||
|
||||
impl pallet_bags_list::Config for Runtime {
|
||||
type RuntimeEvent = RuntimeEvent;
|
||||
type ScoreProvider = Staking;
|
||||
type Score = u64;
|
||||
type WeightInfo = pallet_bags_list::weights::SubstrateWeight<Runtime>;
|
||||
type BagThreshold = BagThreshold;
|
||||
}
|
||||
|
||||
construct_runtime!(
|
||||
pub enum Runtime
|
||||
{
|
||||
System: frame_system,
|
||||
RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip,
|
||||
Timestamp: pallet_timestamp,
|
||||
Sudo: pallet_sudo,
|
||||
Aura: pallet_aura,
|
||||
Grandpa: pallet_grandpa,
|
||||
Balances: pallet_balances,
|
||||
Staking: pallet_staking,
|
||||
BagsList: pallet_bags_list,
|
||||
TransactionPayment: pallet_transaction_payment,
|
||||
ELectionProviderMultiPhase: election_multi_phase,
|
||||
}
|
||||
);
|
||||
|
||||
pub type Address = sp_runtime::MultiAddress<AccountId, ()>;
|
||||
pub type Header = generic::Header<BlockNumber, BlakeTwo256>;
|
||||
pub type Block = generic::Block<Header, UncheckedExtrinsic>;
|
||||
pub type SignedExtra = (
|
||||
frame_system::CheckSpecVersion<Runtime>,
|
||||
frame_system::CheckTxVersion<Runtime>,
|
||||
frame_system::CheckGenesis<Runtime>,
|
||||
frame_system::CheckEra<Runtime>,
|
||||
frame_system::CheckNonce<Runtime>,
|
||||
frame_system::CheckWeight<Runtime>,
|
||||
pallet_transaction_payment::ChargeTransactionPayment<Runtime>
|
||||
);
|
||||
|
||||
pub type UncheckedExtrinsic =
|
||||
generic::UncheckedExtrinsic<Address, RuntimeCall, Signature, SignedExtra>;
|
||||
pub type Executive = frame_executive::Executive<
|
||||
Runtime,
|
||||
Block,
|
||||
frame_system::ChainContext<Runtime>,
|
||||
Runtime,
|
||||
AllPalletsWithSystem
|
||||
>;
|
||||
|
||||
impl_runtime_apis! {
|
||||
impl sp_api::Core<Block> for Runtime {
|
||||
fn version() -> RuntimeVersion {
|
||||
VERSION
|
||||
}
|
||||
|
||||
fn execute_block(block: Block) {
|
||||
Executive::execute_block(block);
|
||||
}
|
||||
|
||||
fn initialize_block(header: &<Block as BlockT>::Header) {
|
||||
Executive::initialize_block(header)
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_api::Metadata<Block> for Runtime {
|
||||
fn metadata() -> OpaqueMetadata {
|
||||
OpaqueMetadata::new(Runtime::metadata().into())
|
||||
}
|
||||
|
||||
fn metadata_at_version(version: u32) -> Option<OpaqueMetadata> {
|
||||
Runtime::metadata_at_version(version)
|
||||
}
|
||||
|
||||
fn metadata_versions() -> sp_std::vec::Vec<u32> {
|
||||
Runtime::metadata_versions()
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_block_builder::BlockBuilder<Block> for Runtime {
|
||||
fn apply_extrinsic(extrinsic: <Block as BlockT>::Extrinsic) -> ApplyExtrinsicResult {
|
||||
Executive::apply_extrinsic(extrinsic)
|
||||
}
|
||||
|
||||
fn finalize_block() -> <Block as BlockT>::Header {
|
||||
Executive::finalize_block()
|
||||
}
|
||||
|
||||
fn inherent_extrinsics(
|
||||
data: inherents::InherentData,
|
||||
) -> Vec<<Block as BlockT>::Extrinsic> {
|
||||
data.create_extrinsics()
|
||||
}
|
||||
|
||||
fn check_inherents(
|
||||
block: Block,
|
||||
data: inherents::InherentData,
|
||||
) -> inherents::CheckInherentsResult {
|
||||
data.check_extrinsics(&block)
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue<Block> for Runtime {
|
||||
fn validate_transaction(
|
||||
source: TransactionSource,
|
||||
tx: <Block as BlockT>::Extrinsic,
|
||||
block_hash: <Block as BlockT>::Hash,
|
||||
) -> TransactionValidity {
|
||||
Executive::validate_transaction(source, tx, block_hash)
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_offchain::OffchainWorkerApi<Block> for Runtime {
|
||||
fn offchain_worker(header: &<Block as BlockT>::Header) {
|
||||
Executive::offchain_worker(header)
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_consensus_aura::AuraApi<Block, AuraId> for Runtime {
|
||||
fn slot_duration() -> sp_consensus_aura::SlotDuration {
|
||||
sp_consensus_aura::SlotDuration::from_millis(Aura::slot_duration())
|
||||
}
|
||||
|
||||
fn authorities() -> Vec<AuraId> {
|
||||
Aura::authorities().into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_session::SessionKeys<Block> for Runtime {
|
||||
fn generate_session_keys(seed: Option<Vec<u8>>) -> Vec<u8> {
|
||||
opaque::SessionKeys::generate(seed)
|
||||
}
|
||||
|
||||
fn decode_session_keys(
|
||||
encoded: Vec<u8>,
|
||||
) -> Option<Vec<(Vec<u8>, KeyTypeId)>> {
|
||||
opaque::SessionKeys::decode_into_raw_public_keys(&encoded)
|
||||
}
|
||||
}
|
||||
|
||||
impl fg_primitives::GrandpaApi<Block> for Runtime {
|
||||
fn grandpa_authorities() -> GrandpaAuthorityList {
|
||||
Grandpa::grandpa_authorities()
|
||||
}
|
||||
|
||||
fn current_set_id() -> fg_primitives::SetId {
|
||||
Grandpa::current_set_id()
|
||||
}
|
||||
|
||||
fn submit_report_equivocation_unsigned_extrinsic(
|
||||
_equivocation_proof: fg_primitives::EquivocationProof<
|
||||
<Block as BlockT>::Hash,
|
||||
NumberFor<Block>,
|
||||
>,
|
||||
_key_owner_proof: fg_primitives::OpaqueKeyOwnershipProof,
|
||||
) -> Option<()> {
|
||||
None
|
||||
}
|
||||
|
||||
fn generate_key_ownership_proof(
|
||||
_set_id: fg_primitives::SetId,
|
||||
_authority_id: GrandpaId,
|
||||
) -> Option<fg_primitives::OpaqueKeyOwnershipProof> {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
impl frame_system_rpc_runtime_api::AccountNonceApi<Block, AccountId, Nonce> for Runtime {
|
||||
fn account_nonce(account: AccountId) -> Nonce {
|
||||
System::account_nonce(account)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentApi<Block, Balance> for Runtime {
|
||||
fn query_info(
|
||||
uxt: <Block as BlockT>::Extrinsic,
|
||||
len: u32,
|
||||
) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
|
||||
TransactionPayment::query_info(uxt, len)
|
||||
}
|
||||
|
||||
fn query_fee_details(
|
||||
uxt: <Block as BlockT>::Extrinsic,
|
||||
len: u32,
|
||||
) -> pallet_transaction_payment::FeeDetails<Balance> {
|
||||
TransactionPayment::query_fee_details(uxt, len)
|
||||
}
|
||||
|
||||
fn query_weight_to_fee(weight: Weight) -> Balance {
|
||||
TransactionPayment::weight_to_fee(weight)
|
||||
}
|
||||
|
||||
fn query_length_to_fee(length: u32) -> Balance {
|
||||
TransactionPayment::length_to_fee(length)
|
||||
}
|
||||
}
|
||||
|
||||
impl pallet_transaction_payment_rpc_runtime_api::TransactionPaymentCallApi<Block, Balance, RuntimeCall> for Runtime {
|
||||
fn query_call_info(call: RuntimeCall, len: u32) -> pallet_transaction_payment_rpc_runtime_api::RuntimeDispatchInfo<Balance> {
|
||||
TransactionPayment::query_call_info(call, len)
|
||||
}
|
||||
|
||||
fn query_call_fee_details(call: RuntimeCall, len: u32) -> pallet_transaction_payment::FeeDetails<Balance> {
|
||||
TransactionPayment::query_call_fee_details(call, len)
|
||||
}
|
||||
|
||||
fn query_weight_to_fee(weight: Weight) -> Balance {
|
||||
TransactionPayment::weight_to_fee(weight)
|
||||
}
|
||||
|
||||
fn query_length_to_fee(length: u32) -> Balance {
|
||||
TransactionPayment::length_to_fee(length)
|
||||
}
|
||||
}
|
||||
|
||||
impl sp_genesis_builder::GenesisBuilder<Block> for Runtime {
|
||||
fn create_default_config() -> Vec<u8> {
|
||||
create_default_config::<RuntimeGenesisConfig>()
|
||||
}
|
||||
|
||||
fn build_config(config: Vec<u8>) -> sp_genesis_builder::Result {
|
||||
build_config::<RuntimeGenesisConfig>(config)
|
||||
}
|
||||
}
|
||||
}
|
||||
441
utils/staking-miner/playground/runtime/src/voter_bags.rs
Executable file
441
utils/staking-miner/playground/runtime/src/voter_bags.rs
Executable file
@@ -0,0 +1,441 @@
|
||||
// This file is part of Ghost Network.
|
||||
|
||||
// Ghost Network 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.
|
||||
|
||||
// Ghost Network 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 Ghost Network. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
//! Autogenerated bag thresholds.
|
||||
//!
|
||||
//! Generated on 2023-06-14T16:02:49.211048528+00:00
|
||||
//! Arguments
|
||||
//! Total issuance: 30000000000000000000000000
|
||||
//! Minimum balance: 100000000000000
|
||||
//! for the casper runtime.
|
||||
|
||||
/// Existential weight for this runtime.
|
||||
#[cfg(any(test, feature = "std"))]
|
||||
#[allow(unused)]
|
||||
pub const EXISTENTIAL_WEIGHT: u64 = 61_489_156;
|
||||
|
||||
/// Constant ratio between bags for this runtime.
|
||||
#[cfg(any(test, feature = "std"))]
|
||||
#[allow(unused)]
|
||||
pub const CONSTANT_RATIO: f64 = 1.1420206998172278;
|
||||
|
||||
/// Upper thresholds delimiting the bag list.
|
||||
pub const THRESHOLDS: [u64; 200] = [
|
||||
61_489_156,
|
||||
70_221_889,
|
||||
80_194_851,
|
||||
91_584_180,
|
||||
104_591_029,
|
||||
119_445_120,
|
||||
136_408_800,
|
||||
155_781_673,
|
||||
177_905_895,
|
||||
203_172_215,
|
||||
232_026_875,
|
||||
264_979_494,
|
||||
302_612_067,
|
||||
345_589_245,
|
||||
394_670_071,
|
||||
450_721_391,
|
||||
514_733_158,
|
||||
587_835_921,
|
||||
671_320_790,
|
||||
766_662_238,
|
||||
875_544_146,
|
||||
999_889_538,
|
||||
1_141_894_550,
|
||||
1_304_067_213,
|
||||
1_489_271_751,
|
||||
1_700_779_167,
|
||||
1_942_325_015,
|
||||
2_218_175_373,
|
||||
2_533_202_192,
|
||||
2_892_969_340,
|
||||
3_303_830_870,
|
||||
3_773_043_242,
|
||||
4_308_893_484,
|
||||
4_920_845_552,
|
||||
5_619_707_481,
|
||||
6_417_822_270,
|
||||
7_329_285_880,
|
||||
8_370_196_190,
|
||||
9_558_937_311,
|
||||
10_916_504_277,
|
||||
12_466_873_854,
|
||||
14_237_428_003,
|
||||
16_259_437_492,
|
||||
18_568_614_183,
|
||||
21_205_741_764,
|
||||
24_217_396_049,
|
||||
27_656_767_584,
|
||||
31_584_601_071,
|
||||
36_070_268_219,
|
||||
41_192_992_954,
|
||||
47_043_250_641,
|
||||
53_724_366_019,
|
||||
61_354_338_078,
|
||||
70_067_924_109,
|
||||
80_019_019_726,
|
||||
91_383_376_906,
|
||||
104_361_708_046,
|
||||
119_183_230_857,
|
||||
136_109_716_710,
|
||||
155_440_113_929,
|
||||
177_515_827_689,
|
||||
202_726_749_766,
|
||||
231_518_144_639,
|
||||
264_398_513_561,
|
||||
301_948_575_488,
|
||||
344_831_523_488,
|
||||
393_804_737_773,
|
||||
449_733_162_223,
|
||||
513_604_580_653,
|
||||
586_547_062_627,
|
||||
669_848_886_937,
|
||||
764_981_294_632,
|
||||
873_624_473_443,
|
||||
997_697_232_539,
|
||||
1_139_390_891_710,
|
||||
1_301_207_983_516,
|
||||
1_486_006_451_943,
|
||||
1_697_050_128_181,
|
||||
1_938_066_375_010,
|
||||
2_213_311_917_881,
|
||||
2_527_648_025_372,
|
||||
2_886_626_366_827,
|
||||
3_296_587_063_555,
|
||||
3_764_770_665_330,
|
||||
4_299_446_029_872,
|
||||
4_910_056_363_861,
|
||||
5_607_386_004_799,
|
||||
6_403_750_889_346,
|
||||
7_313_216_072_106,
|
||||
8_351_844_136_581,
|
||||
9_537_978_885_623,
|
||||
10_892_569_321_801,
|
||||
12_439_539_639_691,
|
||||
14_206_211_764_724,
|
||||
16_223_787_901_302,
|
||||
18_527_901_612_731,
|
||||
21_159_247_165_916,
|
||||
24_164_298_256_025,
|
||||
27_596_128_804_938,
|
||||
31_515_350_330_062,
|
||||
35_991_182_438_923,
|
||||
41_102_675_356_148,
|
||||
46_940_106_074_588,
|
||||
53_606_572_788_796,
|
||||
61_219_815_771_064,
|
||||
69_914_296_849_552,
|
||||
79_843_574_215_355,
|
||||
91_183_014_501_328,
|
||||
104_132_890_032_251,
|
||||
118_921_915_948_622,
|
||||
135_811_289_675_251,
|
||||
155_099_304_078_010,
|
||||
177_126_615_784_334,
|
||||
202_282_261_714_282,
|
||||
231_010_530_083_556,
|
||||
263_818_807_231_171,
|
||||
301_286_538_859_088,
|
||||
344_075_463_953_366,
|
||||
392_941_302_133_960,
|
||||
448_747_100_850_118,
|
||||
512_478_478_153_804,
|
||||
585_261_030_262_475,
|
||||
668_380_211_356_103,
|
||||
763_304_036_716_883,
|
||||
871_709_010_184_730,
|
||||
995_509_733_848_148,
|
||||
1_136_892_722_924_124,
|
||||
1_298_355_023_050_922,
|
||||
1_482_748_312_035_827,
|
||||
1_693_329_264_963_968,
|
||||
1_933_817_072_195_143,
|
||||
2_208_459_126_106_800,
|
||||
2_522_106_036_714_231,
|
||||
2_880_297_301_061_641,
|
||||
3_289_359_139_440_088,
|
||||
3_756_516_226_373_564,
|
||||
4_290_019_289_717_909,
|
||||
4_899_290_831_473_053,
|
||||
5_595_091_543_966_984,
|
||||
6_389_710_360_582_628,
|
||||
7_297_181_497_621_964,
|
||||
8_333_532_320_607_561,
|
||||
9_517_066_412_729_732,
|
||||
10_868_686_844_872_642,
|
||||
12_412_265_356_675_752,
|
||||
14_175_063_968_947_974,
|
||||
16_188_216_473_771_936,
|
||||
18_487_278_306_169_800,
|
||||
21_112_854_508_927_888,
|
||||
24_111_316_881_425_140,
|
||||
27_535_622_978_440_076,
|
||||
31_446_251_423_741_472,
|
||||
35_912_270_057_569_732,
|
||||
41_012_555_783_171_056,
|
||||
46_837_187_656_790_104,
|
||||
53_489_037_825_278_256,
|
||||
61_085_588_409_774_440,
|
||||
69_761_006_424_477_744,
|
||||
79_668_513_376_836_192,
|
||||
90_983_091_400_012_640,
|
||||
103_904_573_712_177_232,
|
||||
118_661_173_984_991_376,
|
||||
135_513_516_955_473_664,
|
||||
154_759_241_468_183_808,
|
||||
176_738_257_244_678_592,
|
||||
201_838_748_223_045_056,
|
||||
230_504_028_495_915_136,
|
||||
263_240_371_933_595_200,
|
||||
300_625_953_775_751_680,
|
||||
343_321_062_114_205_504,
|
||||
392_079_759_617_658_880,
|
||||
447_763_201_462_729_216,
|
||||
511_354_844_686_868_352,
|
||||
583_977_817_584_227_200,
|
||||
666_914_755_915_276_544,
|
||||
761_630_456_268_799_744,
|
||||
869_797_746_670_209_152,
|
||||
993_327_031_351_760_000,
|
||||
1_134_400_031_491_706_240,
|
||||
1_295_508_317_836_843_520,
|
||||
1_479_497_315_755_071_488,
|
||||
1_689_616_559_916_316_672,
|
||||
1_929_577_086_178_408_960,
|
||||
2_203_616_974_308_753_920,
|
||||
2_516_576_199_129_205_248,
|
||||
2_873_982_112_072_913_920,
|
||||
3_282_147_062_891_703_296,
|
||||
3_748_279_885_666_641_408,
|
||||
4_280_613_218_139_856_384,
|
||||
4_888_548_903_026_954_240,
|
||||
5_582_824_039_325_583_360,
|
||||
6_375_700_616_347_044_864,
|
||||
7_281_182_079_705_782_272,
|
||||
8_315_260_654_162_254_848,
|
||||
9_496_199_791_429_038_080,
|
||||
10_844_856_731_412_002_816,
|
||||
12_385_050_873_824_708_608,
|
||||
14_143_984_466_197_262_336,
|
||||
16_152_723_038_290_595_840,
|
||||
18_446_744_073_709_551_615,
|
||||
];
|
||||
|
||||
/// Upper thresholds delimiting the bag list.
|
||||
#[allow(dead_code)]
|
||||
pub const THRESHOLDS_BALANCES: [u128; 200] = [
|
||||
61_489_156,
|
||||
70_221_889,
|
||||
80_194_851,
|
||||
91_584_180,
|
||||
104_591_029,
|
||||
119_445_120,
|
||||
136_408_800,
|
||||
155_781_673,
|
||||
177_905_895,
|
||||
203_172_215,
|
||||
232_026_875,
|
||||
264_979_494,
|
||||
302_612_067,
|
||||
345_589_245,
|
||||
394_670_071,
|
||||
450_721_391,
|
||||
514_733_158,
|
||||
587_835_921,
|
||||
671_320_790,
|
||||
766_662_238,
|
||||
875_544_146,
|
||||
999_889_538,
|
||||
1_141_894_550,
|
||||
1_304_067_213,
|
||||
1_489_271_751,
|
||||
1_700_779_167,
|
||||
1_942_325_015,
|
||||
2_218_175_373,
|
||||
2_533_202_192,
|
||||
2_892_969_340,
|
||||
3_303_830_870,
|
||||
3_773_043_242,
|
||||
4_308_893_484,
|
||||
4_920_845_552,
|
||||
5_619_707_481,
|
||||
6_417_822_270,
|
||||
7_329_285_880,
|
||||
8_370_196_190,
|
||||
9_558_937_311,
|
||||
10_916_504_277,
|
||||
12_466_873_854,
|
||||
14_237_428_003,
|
||||
16_259_437_492,
|
||||
18_568_614_183,
|
||||
21_205_741_764,
|
||||
24_217_396_049,
|
||||
27_656_767_584,
|
||||
31_584_601_071,
|
||||
36_070_268_219,
|
||||
41_192_992_954,
|
||||
47_043_250_641,
|
||||
53_724_366_019,
|
||||
61_354_338_078,
|
||||
70_067_924_109,
|
||||
80_019_019_726,
|
||||
91_383_376_906,
|
||||
104_361_708_046,
|
||||
119_183_230_857,
|
||||
136_109_716_710,
|
||||
155_440_113_929,
|
||||
177_515_827_689,
|
||||
202_726_749_766,
|
||||
231_518_144_639,
|
||||
264_398_513_561,
|
||||
301_948_575_488,
|
||||
344_831_523_488,
|
||||
393_804_737_773,
|
||||
449_733_162_223,
|
||||
513_604_580_653,
|
||||
586_547_062_627,
|
||||
669_848_886_937,
|
||||
764_981_294_632,
|
||||
873_624_473_443,
|
||||
997_697_232_539,
|
||||
1_139_390_891_710,
|
||||
1_301_207_983_516,
|
||||
1_486_006_451_943,
|
||||
1_697_050_128_181,
|
||||
1_938_066_375_010,
|
||||
2_213_311_917_881,
|
||||
2_527_648_025_372,
|
||||
2_886_626_366_827,
|
||||
3_296_587_063_555,
|
||||
3_764_770_665_330,
|
||||
4_299_446_029_872,
|
||||
4_910_056_363_861,
|
||||
5_607_386_004_799,
|
||||
6_403_750_889_346,
|
||||
7_313_216_072_106,
|
||||
8_351_844_136_581,
|
||||
9_537_978_885_623,
|
||||
10_892_569_321_801,
|
||||
12_439_539_639_691,
|
||||
14_206_211_764_724,
|
||||
16_223_787_901_302,
|
||||
18_527_901_612_731,
|
||||
21_159_247_165_916,
|
||||
24_164_298_256_025,
|
||||
27_596_128_804_938,
|
||||
31_515_350_330_062,
|
||||
35_991_182_438_923,
|
||||
41_102_675_356_148,
|
||||
46_940_106_074_588,
|
||||
53_606_572_788_796,
|
||||
61_219_815_771_064,
|
||||
69_914_296_849_552,
|
||||
79_843_574_215_355,
|
||||
91_183_014_501_328,
|
||||
104_132_890_032_251,
|
||||
118_921_915_948_622,
|
||||
135_811_289_675_251,
|
||||
155_099_304_078_010,
|
||||
177_126_615_784_334,
|
||||
202_282_261_714_282,
|
||||
231_010_530_083_556,
|
||||
263_818_807_231_171,
|
||||
301_286_538_859_088,
|
||||
344_075_463_953_366,
|
||||
392_941_302_133_960,
|
||||
448_747_100_850_118,
|
||||
512_478_478_153_804,
|
||||
585_261_030_262_475,
|
||||
668_380_211_356_103,
|
||||
763_304_036_716_883,
|
||||
871_709_010_184_730,
|
||||
995_509_733_848_148,
|
||||
1_136_892_722_924_124,
|
||||
1_298_355_023_050_922,
|
||||
1_482_748_312_035_827,
|
||||
1_693_329_264_963_968,
|
||||
1_933_817_072_195_143,
|
||||
2_208_459_126_106_800,
|
||||
2_522_106_036_714_231,
|
||||
2_880_297_301_061_641,
|
||||
3_289_359_139_440_088,
|
||||
3_756_516_226_373_564,
|
||||
4_290_019_289_717_909,
|
||||
4_899_290_831_473_053,
|
||||
5_595_091_543_966_984,
|
||||
6_389_710_360_582_628,
|
||||
7_297_181_497_621_964,
|
||||
8_333_532_320_607_561,
|
||||
9_517_066_412_729_732,
|
||||
10_868_686_844_872_642,
|
||||
12_412_265_356_675_752,
|
||||
14_175_063_968_947_974,
|
||||
16_188_216_473_771_936,
|
||||
18_487_278_306_169_800,
|
||||
21_112_854_508_927_888,
|
||||
24_111_316_881_425_140,
|
||||
27_535_622_978_440_076,
|
||||
31_446_251_423_741_472,
|
||||
35_912_270_057_569_732,
|
||||
41_012_555_783_171_056,
|
||||
46_837_187_656_790_104,
|
||||
53_489_037_825_278_256,
|
||||
61_085_588_409_774_440,
|
||||
69_761_006_424_477_744,
|
||||
79_668_513_376_836_192,
|
||||
90_983_091_400_012_640,
|
||||
103_904_573_712_177_232,
|
||||
118_661_173_984_991_376,
|
||||
135_513_516_955_473_664,
|
||||
154_759_241_468_183_808,
|
||||
176_738_257_244_678_592,
|
||||
201_838_748_223_045_056,
|
||||
230_504_028_495_915_136,
|
||||
263_240_371_933_595_200,
|
||||
300_625_953_775_751_680,
|
||||
343_321_062_114_205_504,
|
||||
392_079_759_617_658_880,
|
||||
447_763_201_462_729_216,
|
||||
511_354_844_686_868_352,
|
||||
583_977_817_584_227_200,
|
||||
666_914_755_915_276_544,
|
||||
761_630_456_268_799_744,
|
||||
869_797_746_670_209_152,
|
||||
993_327_031_351_760_000,
|
||||
1_134_400_031_491_706_240,
|
||||
1_295_508_317_836_843_520,
|
||||
1_479_497_315_755_071_488,
|
||||
1_689_616_559_916_316_672,
|
||||
1_929_577_086_178_408_960,
|
||||
2_203_616_974_308_753_920,
|
||||
2_516_576_199_129_205_248,
|
||||
2_873_982_112_072_913_920,
|
||||
3_282_147_062_891_703_296,
|
||||
3_748_279_885_666_641_408,
|
||||
4_280_613_218_139_856_384,
|
||||
4_888_548_903_026_954_240,
|
||||
5_582_824_039_325_583_360,
|
||||
6_375_700_616_347_044_864,
|
||||
7_281_182_079_705_782_272,
|
||||
8_315_260_654_162_254_848,
|
||||
9_496_199_791_429_038_080,
|
||||
10_844_856_731_412_002_816,
|
||||
12_385_050_873_824_708_608,
|
||||
14_143_984_466_197_262_336,
|
||||
16_152_723_038_290_595_840,
|
||||
18_446_744_073_709_551_615,
|
||||
];
|
||||
Reference in New Issue
Block a user