Substrate中Elections模块分析

Substrate中Elections模块分析

Elections支持议会的选举机制,基本功能,设置所需要的议会数量,多久可以轮换这些议会成员席位。多久进行投票统计,每个人可以支持投票,锁定,计票,然后是更新议会成员,选出Top的议会成员,当然任何人都可以提名候选人,大家投票支持,通过或者不通过后都可以解锁被锁定时的币。

记录一个投票人的基本信息

/// The activity status of a voter.
#[derive(PartialEq, Eq, Copy, Clone, Encode, Decode, Default, RuntimeDebug)]
pub struct VoterInfo {
    /// Last VoteIndex in which this voter assigned (or initialized) approvals.
    last_active: VoteIndex,
    /// Last VoteIndex in which one of this voter's approvals won.
    /// Note that `last_win = N` indicates a last win at index `N-1`, hence `last_win = 0` means no
    /// win ever.
    last_win: VoteIndex,
    /// The amount of stored weight as a result of not winning but changing approvals.
    pot: Balance,
    /// Current staked amount. A lock equal to this value always exists.
    stake: Balance,
}

last_active:投票人参与的投票次数索引,last_win:投票人参与投票,获得通过的投票次数索引,pot:用来改变投票结果的币额,stake:现在质押的币额。

Trait

/// 投票选举人的Currency管理,主要是LockableCurrency和ReservableCurrency
type Currency

/// 当惩罚一个验证节点时,资产减少的不平衡处理器
type BadPresentation: OnUnbalanced>;

/// 当惩罚一个不合法收割掉账号时,资产减少的不平衡处理器
type BadReaper: OnUnbalanced>;

/// 当提交一个坏的`voter_index`时,资产减少的不平衡处理器
type BadVoterIndex: OnUnbalanced>;

/// 当一个候选人失去候选资格,不再是runner up的时候,资产减少的不平衡处理器
type LoserCandidate: OnUnbalanced>;

/// 当需要进行成员改变的时候,需要进行的处理
type ChangeMembers: ChangeMembers;

/// 提交一个候选人,需要绑定的币额,默认合理的是9个Token
type CandidacyBond: Get>;

/// 提交投票选举时,需要锁定的币额
type VotingBond: Get>;

/// 每一次投票选举提交时的手续费,除非提交一个hole索引,不需要付手续费
type VotingFee: Get>;

/// 可用于投票锁定的最低币额
type MinimumVotingLock: Get>;

/// 如果提供一个非法的代表,每个投票人的惩罚币额,默认1块
type PresentSlashPerVoter: Get>;

/// 直到下一次投票选举,runners-up能够持续的提案数量,默认2个
type CarryCount: Get;

/// 在目标选民最后一次投票之后,需要通过多少个投票账号,才能在他们的提案没有意义的情况下被收割。合理的默认值是1。
type InactiveGracePeriod: Get;

/// 多久去检查新的投票,默认是1000个区块时间长度
type VotingPeriod: Get;

/// 重量累积时的衰减系数。通常应将其设置为至少为`membership_size -1`,以确保集体安全。当设置为`N`时,表示`(1/N)^t`在第t步的权值增量处衰减。0将导致不添加任何权重(正常的提案投票)。合理的默认值是24。
type DecayRatio: Get;

Storage

// ---- 参数
/// 投票结束后,给每个得票最多的候选人多少时间进行自我介绍。
pub PresentationDuration get(fn presentation_duration) config(): T::BlockNumber;
/// 每个位置活跃的时间。
pub TermDuration get(fn term_duration) config(): T::BlockNumber;
/// 议会所需的成员数量
pub DesiredSeats get(fn desired_seats) config(): u32;

// ---- 不变的状态 (always relevant, changes only at the finalization of voting)

/// 当前会员。当投票正在进行时,这仍然应该用于执行事务。区块号(元组中的第二个元素)是其位置处于活动状态的块(根据当选成员时的区块号和他们的任期计算)
pub Members get(fn members) config(): Vec<(T::AccountId, T::BlockNumber)>;
/// 总的已经发生的投票轮次
pub VoteCount get(fn vote_index): VoteIndex;

// ---- 持续的状态 (always relevant, changes constantly)

// 每个投票者的投票列表。投票以数值形式存储,并按位解析。为了获得人类可读的表示(`Vec`),使用[` all_approvals_of`]。此外,每个标量向量都用`APPROVAL_SET_SIZE`的长度进行分块。
pub ApprovalsOf get(fn approvals_of): map (T::AccountId, SetIndex) => Vec;
/// 投票索引和列表槽,候选人“谁”已注册或“没有”,如果他们目前没有注册。
pub RegisterInfoOf get(fn candidate_reg_info): map T::AccountId => Option<(VoteIndex, u32)>;
/// 投票人的基本信息
pub VoterInfoOf get(fn voter_info): map T::AccountId => Option>>;
/// 投票人列表 (chunked and capped at [`VOTER_SET_SIZE`]).
pub Voters get(fn voters): map SetIndex => Vec>;
/// 存储投票者的下一个免费集合。这将继续增长。
pub NextVoterSet get(fn next_nonfull_voter_set): SetIndex = 0;
/// 现在投票人总数
pub VoterCount get(fn voter_count): SetIndex = 0;
/// 现在候选人列表
pub Candidates get(fn candidates): Vec; // has holes
/// 现在活跃的候选人总数
pub CandidateCount get(fn candidate_count): u32;

// ---- 临时状态 (only relevant during finalization/presentation)

/// 持有下次点票时将免费的席位的账户。
pub NextFinalize get(fn next_finalize): Option<(T::BlockNumber, u32, Vec)>;
/// 如果我们在演示阶段,得到排行榜。第一个元素是每个条目的权重;它可以是直接加和的批准股份,也可以是加权的批准股份。从低到高排序。
pub Leaderboard get(fn leaderboard): Option, T::AccountId)> >;

/// 谁能投票给谁。value是基金持有账户,key是选票交易发送账户。
pub Proxy get(fn proxy): map T::AccountId => Option;
  • fn set_approvals(origin, votes: Vec, #[compact] index: VoteIndex, hint: SetIndex) -> Result

    • 批准候选人,在这段时间内候选人注册了,批准将是有效的。将无限期锁定调用者的所有余额。只有[retract_voter]和[reap_inactive_voter]能解锁余额。
  • fn proxy_set_approvals(origin,votes: Vec, #[compact] index: VoteIndex,hint: SetIndex) -> Result

    • 代理批准候选人。
  • fn reap_inactive_voter(origin,#[compact] reporter_index: u32,who: ::Source,#[compact] who_index: u32,#[compact] assumed_vote_index: VoteIndex)

    • 移除一个投票者,所有被批准的候选人索引要么未注册,要么在投票人给出他们最后的批准集合后注册成为一个候选人。
  • fn retract_voter(origin,#[compact] index:u32)

    • 移除一个投票者,所有投票者都能够取消并会返回其锁住的存款。
  • fn submit_candidacy(origin,#[compact] slot:u32)

    • 某人申请候选资格。
  • fn present_winer(origin,candidate: ::Source,#[compact] total: BalanceOf,#[compact] index: VoteIndex) -> Result

    • 声称自己是top候选人中的一个,top候选人是carry_count + desired_seats,条件是在这个代表期间是活跃的,候选人还需要有投票支持着,并且要有足够的币额用来做潜在的惩罚金。
  • fn set_desired_seats(origin, #[compact] count:u32)

    • 设置所需要的成员数量。
  • fn remove_member(origin,who: ::Source)

    • 将某个特定的成员移除。
  • fn set_presentation_duration(origin,#[compact] count: T::BlockNumber)

    • 设置presentation时长。
  • fn set_term_duration(origin,#[compact] count: T::BlockNumber)

    • 设置term时长。
  • pub fn presentation_active() -> bool

    • 查询现在是否在一个presentation阶段
  • pub fn is_a_candidate(who: &T::AccountId) -> bool

    • 查询某个账号在此时是否是一个候选人
  • pub fn will_still_be_member_at(who: &T::AccountId, n: T::BlockNumber) -> bool

    • 在区块高度n的时候,某个账号是否还有席位
  • pub fn next_vote_from(n: T::BlockNumber) -> T::BlockNumber

    • 在不低于区块高度n的时候,返回具体区块高度能让投票开始
  • pub fn next_tally() -> Option

    • 返回区块高度,能让为下一次选举的计数开始
  • pub fn bool_to_flag(x: Vec) -> Vec

    • 将布尔值的vec转成flags的vec
  • pub fn flag_to_bool(chunk: Vec) -> Vec

    • 将flags的vec转化成布尔值的vec

你可能感兴趣的:(Substrate中Elections模块分析)