什么是元力?
Force是一个全球加密货币生态系统,其成员使用我们的智能合约即时利润分配工具和算法互相帮助以实现财务福利。
META FORCE系统属于我们的社区并且是完全去中心化的,这意味着它是透明的、安全的并且可以抵抗外部影响。
智能合约是一种自执行算法(程序代码)。它保证了在区块链内执行逻辑或传输的透明性和安全性。
const_assert!(NORMAL_DISPATCH_RATIO.deconstruct() >= AVERAGE_ON_INITIALIZE_RATIO.deconstruct());
impl frame_system::Config for Runtime {
type BaseCallFilter = Everything;
type BlockWeights = RuntimeBlockWeights;
type BlockLength = RuntimeBlockLength;
type DbWeight = RocksDbWeight;
type Origin = Origin;
type Call = Call;
type Index = Index;
type BlockNumber = BlockNumber;
type Hash = Hash;
type Hashing = BlakeTwo256;
type AccountId = AccountId;
type Lookup = Indices;
type Header = generic::Header<BlockNumber, BlakeTwo256>;
type Event = Event;
type BlockHashCount = BlockHashCount;
type Version = Version;
type PalletInfo = PalletInfo;
type AccountData = pallet_balances::AccountData<Balance>;
type OnNewAccount = ();
type OnKilledAccount = ();
type SystemWeightInfo = frame_system::weights::SubstrateWeight<Runtime>;
type SS58Prefix = ConstU16<42>;
type OnSetCode = ();
type MaxConsumers = ConstU32<16>;
}
impl pallet_randomness_collective_flip::Config for Runtime {}
impl pallet_utility::Config for Runtime {
type Event = Event;
type Call = Call;
type PalletsOrigin = OriginCaller;
type WeightInfo = pallet_utility::weights::SubstrateWeight<Runtime>;
}
parameter_types! {
// One storage item; key size is 32; value is size 4+4+16+32 bytes = 56 bytes.
pub const DepositBase: Balance = deposit(1, 88);
// Additional storage item size of 32 bytes.
pub const DepositFactor: Balance = deposit(0, 32);
}
impl pallet_multisig::Config for Runtime {
type Event = Event;
type Call = Call;
type Currency = Balances;
type DepositBase = DepositBase;
type DepositFactor = DepositFactor;
type MaxSignatories = ConstU16<100>;
type WeightInfo = pallet_multisig::weights::SubstrateWeight<Runtime>;
}
parameter_types! {
// One storage item; key size 32, value size 8; .
pub const ProxyDepositBase: Balance = deposit(1, 8);
// Additional storage item size of 33 bytes.
pub const ProxyDepositFactor: Balance = deposit(0, 33);
pub const AnnouncementDepositBase: Balance = deposit(1, 8);
pub const AnnouncementDepositFactor: Balance = deposit(0, 66);
}
/// The type used to represent the kinds of proxying allowed.
[derive(
Copy,
Clone,
Eq,
PartialEq,
Ord,
PartialOrd,
Encode,
Decode,
RuntimeDebug,
MaxEncodedLen,
scale_info::TypeInfo,
)]
pub enum ProxyType {
Any,
NonTransfer,
Governance,
Staking,
}
impl Default for ProxyType {
fn default() -> Self {
Self::Any
}
}
impl InstanceFilter for ProxyType {
fn filter(&self, c: &Call) -> bool {
match self {
ProxyType::Any => true,
ProxyType::NonTransfer => !matches!(
c,
Call::Balances(..) |
Call::Assets(..) | Call::Uniques(..) |
Call::Vesting(pallet_vesting::Call::vested_transfer { .. }) |
Call::Indices(pallet_indices::Call::transfer { .. })
),
ProxyType::Governance => matches!(
c,
Call::Democracy(..) |
Call::Council(..) | Call::Society(..) |
Call::TechnicalCommittee(..) |
Call::Elections(..) | Call::Treasury(..)
),
ProxyType::Staking => matches!(c, Call::Staking(..)),
}
}
fn is_superset(&self, o: &Self) -> bool {
match (self, o) {
(x, y) if x == y => true,
(ProxyType::Any, _) => true,
(_, ProxyType::Any) => false,
(ProxyType::NonTransfer, _) => true,
_ => false,
}
}
}
impl pallet_proxy::Config for Runtime {
type Event = Event;
type Call = Call;
type Currency = Balances;
type ProxyType = ProxyType;
type ProxyDepositBase = ProxyDepositBase;
type ProxyDepositFactor = ProxyDepositFactor;
type MaxProxies = ConstU32<32>;
type WeightInfo = pallet_proxy::weights::SubstrateWeight<Runtime>;
type MaxPending = ConstU32<32>;
type CallHasher = BlakeTwo256;
type AnnouncementDepositBase = AnnouncementDepositBase;
type AnnouncementDepositFactor = AnnouncementDepositFactor;
}
parameter_types! {
pub MaximumSchedulerWeight: Weight = Perbill::from_percent(80) *
RuntimeBlockWeights::get().max_block;
// Retry a scheduled item every 10 blocks (1 minute) until the preimage exists.
pub const NoPreimagePostponement: Option<u32> = Some(10);
}
impl pallet_scheduler::Config for Runtime {
type Event = Event;
type Origin = Origin;
type PalletsOrigin = OriginCaller;
type Call = Call;
type MaximumWeight = MaximumSchedulerWeight;
type ScheduleOrigin = EnsureRoot<AccountId>;
type MaxScheduledPerBlock = ConstU32<50>;
type WeightInfo = pallet_scheduler::weights::SubstrateWeight<Runtime>;
type OriginPrivilegeCmp = EqualPrivilegeOnly;
type PreimageProvider = Preimage;
type NoPreimagePostponement = NoPreimagePostponement;
}
parameter_types! {
pub const PreimageMaxSize: u32 = 4096 * 1024;
pub const PreimageBaseDeposit: Balance = 1 * DOLLARS;
// One cent: $10,000 / MB
pub const PreimageByteDeposit: Balance = 1 * CENTS;
}
impl pallet_preimage::Config for Runtime {
type WeightInfo = pallet_preimage::weights::SubstrateWeight<Runtime>;
type Event = Event;
type Currency = Balances;
type ManagerOrigin = EnsureRoot<AccountId>;
type MaxSize = PreimageMaxSize;
type BaseDeposit = PreimageBaseDeposit;
type ByteDeposit = PreimageByteDeposit;
}
parameter_types! {
// NOTE: Currently it is not possible to change the epoch duration after the chain has started.
// Attempting to do so will brick block production.
pub const EpochDuration: u64 = EPOCH_DURATION_IN_SLOTS;
pub const ExpectedBlockTime: Moment = MILLISECS_PER_BLOCK;
pub const ReportLongevity: u64 =
BondingDuration::get() as u64 * SessionsPerEra::get() as u64 * EpochDuration::get();
}
impl pallet_babe::Config for Runtime {
type EpochDuration = EpochDuration;
type ExpectedBlockTime = ExpectedBlockTime;
type EpochChangeTrigger = pallet_babe::ExternalTrigger;
type DisabledValidators = Session;
type KeyOwnerProofSystem = Historical;
type KeyOwnerProof = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
pallet_babe::AuthorityId,
)>>::Proof;
type KeyOwnerIdentification = <Self::KeyOwnerProofSystem as KeyOwnerProofSystem<(
KeyTypeId,
pallet_babe::AuthorityId,
)>>::IdentificationTuple;
type HandleEquivocation =
pallet_babe::EquivocationHandler<Self::KeyOwnerIdentification, Offences, ReportLongevity>;
type WeightInfo = ();
type MaxAuthorities = MaxAuthorities;
}
parameter_types! {
pub const IndexDeposit: Balance = 1 * DOLLARS;
}
impl pallet_indices::Config for Runtime {
type AccountIndex = AccountIndex;
type Currency = Balances;
type Deposit = IndexDeposit;
type Event = Event;
type WeightInfo = pallet_indices::weights::SubstrateWeight<Runtime>;
}
parameter_types! {
pub const ExistentialDeposit: Balance = 1 * DOLLARS;
// For weight estimation, we assume that the most locks on an individual account will be 50.
// This number may need to be adjusted in the future if this assumption no longer holds true.
pub const MaxLocks: u32 = 50;
pub const MaxReserves: u32 = 50;
}
impl pallet_balances::Config for Runtime {
type MaxLocks = MaxLocks;
type MaxReserves = MaxReserves;
type ReserveIdentifier = [u8; 8];
type Balance = Balance;
type DustRemoval = ();
type Event = Event;
type ExistentialDeposit = ExistentialDeposit;
type AccountStore = frame_system::Pallet<Runtime>;
type WeightInfo = pallet_balances::weights::SubstrateWeight<Runtime>;
}
parameter_types! {
pub const TransactionByteFee: Balance = 10 * MILLICENTS;
pub const OperationalFeeMultiplier: u8 = 5;
pub const TargetBlockFullness: Perquintill = Perquintill::from_percent(25);
pub AdjustmentVariable: Multiplier = Multiplier::saturating_from_rational(1, 100_000);
pub MinimumMultiplier: Multiplier = Multiplier::saturating_from_rational(1, 1_000_000_000u128);
}
impl pallet_transaction_payment::Config for Runtime {
type OnChargeTransaction = CurrencyAdapter<Balances, DealWithFees>;
type OperationalFeeMultiplier = OperationalFeeMultiplier;
type WeightToFee = IdentityFee<Balance>;
type LengthToFee = ConstantMultiplier<Balance, TransactionByteFee>;
type FeeMultiplierUpdate =
TargetedFeeAdjustment<Self, TargetBlockFullness, AdjustmentVariable, MinimumMultiplier>;
}
impl pallet_asset_tx_payment::Config for Runtime {
type Fungibles = Assets;
type OnChargeAssetTransaction = pallet_asset_tx_payment::FungiblesAdapter<
pallet_assets::BalanceToAssetBalance<Balances, Runtime, ConvertInto>,
CreditToBlockAuthor,
>;
}
parameter_types! {
pub const MinimumPeriod: Moment = SLOT_DURATION / 2;
}
impl pallet_timestamp::Config for Runtime {
type Moment = Moment;
type OnTimestampSet = Babe;
type MinimumPeriod = MinimumPeriod;
type WeightInfo = pallet_timestamp::weights::SubstrateWeight<Runtime>;
}
parameter_types! {
pub const UncleGenerations: BlockNumber = 5;
}
impl pallet_authorship::Config for Runtime {
type FindAuthor = pallet_session::FindAccountFromAuthorIndex<Self, Babe>;
type UncleGenerations = UncleGenerations;
type FilterUncle = ();
type EventHandler = (Staking, ImOnline);
}
impl_opaque_keys! {
pub struct SessionKeys {
pub grandpa: Grandpa,
pub babe: Babe,
pub im_online: ImOnline,
pub authority_discovery: AuthorityDiscovery,
}
}
impl pallet_session::Config for Runtime {
type Event = Event;
type ValidatorId = <Self as frame_system::Config>::AccountId;
type ValidatorIdOf = pallet_staking::StashOf<Self>;
type ShouldEndSession = Babe;
type NextSessionRotation = Babe;
type SessionManager = pallet_session::historical::NoteHistoricalRoot<Self, Staking>;
type SessionHandler = <SessionKeys as OpaqueKeys>::KeyTypeIdProviders;
type Keys = SessionKeys;
type WeightInfo = pallet_session::weights::SubstrateWeight<Runtime>;
}
impl pallet_session::historical::Config for Runtime {
type FullIdentification = pallet_staking::Exposure<AccountId, Balance>;
type FullIdentificationOf = pallet_staking::ExposureOf<Runtime>;
}
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 SessionsPerEra: sp_staking::SessionIndex = 6;
pub const BondingDuration: sp_staking::EraIndex = 24 * 28;
pub const SlashDeferDuration: sp_staking::EraIndex = 24 * 7; // 1/4 the bonding duration.
pub const RewardCurve: &'static PiecewiseLinear<'static> = &REWARD_CURVE;
pub const MaxNominatorRewardedPerValidator: u32 = 256;
pub const OffendingValidatorsThreshold: Perbill = Perbill::from_percent(17);
pub OffchainRepeat: BlockNumber = 5;
}
pub struct StakingBenchmarkingConfig;
impl pallet_staking::BenchmarkingConfig for StakingBenchmarkingConfig {
type MaxNominators = ConstU32<1000>;
type MaxValidators = ConstU32<1000>;
}
impl pallet_staking::Config for Runtime {
type MaxNominations = MaxNominations;
type Currency = Balances;
type CurrencyBalance = Balance;
type UnixTime = Timestamp;
type CurrencyToVote = U128CurrencyToVote;
type RewardRemainder = Treasury;
type Event = Event;
type Slash = Treasury; // send the slashed funds to the treasury.
type Reward = (); // rewards are minted from the void
type SessionsPerEra = SessionsPerEra;
type BondingDuration = BondingDuration;
type SlashDeferDuration = SlashDeferDuration;
/// A super-majority of the council can cancel the slash.
type SlashCancelOrigin = EitherOfDiverse<
EnsureRoot<AccountId>,
pallet_collective::EnsureProportionAtLeast<AccountId, CouncilCollective, 3, 4>,
>;
type SessionInterface = Self;
type EraPayout = pallet_staking::ConvertCurve<RewardCurve>;
type NextNewSession = Session;
type MaxNominatorRewardedPerValidator = MaxNominatorRewardedPerValidator;
type OffendingValidatorsThreshold = OffendingValidatorsThreshold;
type ElectionProvider = ElectionProviderMultiPhase;
type GenesisElectionProvider = onchain::UnboundedExecution<OnChainSeqPhragmen>;
type VoterList = BagsList;
type MaxUnlockingChunks = ConstU32<32>;
type OnStakerSlash = NominationPools;
type WeightInfo = pallet_staking::weights::SubstrateWeight<Runtime>;
type BenchmarkingConfig = StakingBenchmarkingConfig;
}
parameter_types! {
// phase durations. 1/4 of the last session for each.
pub const SignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4;
pub const UnsignedPhase: u32 = EPOCH_DURATION_IN_BLOCKS / 4;
// signed config
pub const SignedRewardBase: Balance = 1 * DOLLARS;
pub const SignedDepositBase: Balance = 1 * DOLLARS;
pub const SignedDepositByte: Balance = 1 * CENTS;
pub BetterUnsignedThreshold: Perbill = Perbill::from_rational(1u32, 10_000);
// miner configs
pub const MultiPhaseUnsignedPriority: TransactionPriority = StakingUnsignedPriority::get() - 1u64;
pub MinerMaxWeight: Weight = RuntimeBlockWeights::get()
.get(DispatchClass::Normal)
.max_extrinsic.expect("Normal extrinsics have a weight limit configured; qed")
.saturating_sub(BlockExecutionWeight::get());
// Solution can occupy 90% of normal block size
pub MinerMaxLength: u32 = Perbill::from_rational(9u32, 10) *
*RuntimeBlockLength::get()
.max
.get(DispatchClass::Normal);
}
frame_election_provider_support::generate_solution_type!(
#[compact]
pub struct NposSolution16::<
VoterIndex = u32,
TargetIndex = u16,
Accuracy = sp_runtime::PerU16,
MaxVoters = MaxElectingVoters,
>(16)
);
parameter_types! {
pub MaxNominations: u32 = <NposSolution16 as frame_election_provider_support::NposSolution>::LIMIT as u32;
pub MaxElectingVoters: u32 = 10_000;
}
/// The numbers configured here could always be more than the the maximum limits of staking pallet
/// to ensure election snapshot will not run out of memory. For now, we set them to smaller values
/// since the staking is bounded and the weight pipeline takes hours for this single pallet.
pub struct ElectionProviderBenchmarkConfig;
impl pallet_election_provider_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_TARGETS: [u32; 2] = [200, 400];
const SNAPSHOT_MAXIMUM_VOTERS: u32 = 1000;
const MINER_MAXIMUM_VOTERS: u32 = 1000;
const MAXIMUM_TARGETS: u32 = 300;