Substrate中elections-phragmen模块分析

Substrate中elections-phragmen模块分析

Term和Round

选举在rounds中进行:每“N”个区块轮次,所有以前的成员都已退役,并选出一个新的集合(该集合可能与前一个集合有交集,也可能与前一个集合没有交集)。每轮持续一定数量的区块,由“TermDuration”存储项定义。在这个上下文中,单词term和round可以互换使用。

“TermDuration”在一轮游戏中可能会改变。这可以缩短或延长轮的长度。下一轮选举的区块号从不存储,而是始终动态地检查。基于当前块号和“TermDuration”,满足条件“BlockNumber % TermDuration == 0”总是会触发新一轮的选举。

Voting

选民可以通过提供帐户id列表为任意一组候选人投票。无效选票(投票给非候选人)在选举中被忽略。然而,选民可能会投票给未来的候选人。选民在投票时保留锁定币。每个投票都定义了一个value。这个金额从投票者的账户中锁定,并表示投票的权重。选民可以随时更新他们的投票,再次调用vote()。这将保持键不变,但可以选择更改锁定的value。在一轮之后,投票将被保留,并且可能在以后的几轮仍然有效。一个投票者负责调用remove_voter,一旦他们完成了锁定币的取回并移除锁。

选民们还报告说,其他一些选民已经不存在了,无法获得他们的支持。一旦所有他们投票支持的候选人不再是有效的候选人或成员,该投票者就是死的了。在报道时,如果目标投票者实际上已经死亡,报告者将获得目标投票者的锁定币。目标投票者将失去他们的锁定币并被移除。如果目标投票者没有死亡,报告者就会被惩罚并移走。为了防止被报告,投票者应该在他们处于不存在状态时手动提交remove_voter()

Candidacy and Members

候选人在提交候选人资格时也保留一份保证书。候选人不能收回自己的候选人资格。候选人可能会出现以下情况之一:

  • 获胜者:获胜者将保留为会员。他们必须保留一份锁仓币,并自动被计算为下次选举的候选人。
  • 失败者:任何没有获胜的候选人都是失败者。失败者可能是一个出局的成员,这意味着他们是一个未能保留其位置的活跃成员。在这种情况下,即将离任的成员将取回他们的锁仓币。否则,败选候选人的选票就会大幅减少。
  • 亚军:亚军是紧随获胜者之后的最佳候选人。要保留的runners_up的数量是可配置的。当候选人被remove_member()踢出时,亚军被使用来代替其位置。

请注意,由于成员是下一轮选举的默认候选人,并且选票保存在存储器中,因此,如果没有进一步的输入,选举系统是完全稳定的。这意味着,如果系统有一组特定的候选人C和选民V,导致一组成员M当选,只要VC不取消他们的候选资格和选票,M将在每一轮结束时继续获得连任。

const

MAXMUM_VOTE: 每个投票人能最多投票次数,默认16

Storage

/// 现在当选的议员 
pub Members get(fn members): Vec<(T::AccountId, BalanceOf)>;
/// 现在的候选替补,根据功绩,从低到高排序
pub RunnersUp get(fn runners_up): Vec<(T::AccountId, BalanceOf)>;
/// 到目前已经发生的选举轮次,不包括将要到来的这一轮
pub ElectionRounds get(fn election_rounds): u32 = Zero::zero();

/// 指定某个投票者,其投具体的哪些投票
pub VotesOf get(fn votes_of): linked_map T::AccountId => Vec;
/// 投票者锁定的币
pub StakeOf get(fn stake_of): map T::AccountId => BalanceOf;

/// 现在的议会成员候选列表,现在已经是议员了,就不会在这个列表中
pub Candidates get(fn candidates): Vec;

/// 存储格式是否改变了,如果都是使用老版本存储格式,就返回false,其他情况就返回true
DidMigrate: bool;

Module

  • fn vote(origin, votes: Vec, #[compact] value: BalanceOf)

    • 给正在进行投票选举的候选人进行投靠,一次可以给多个候选人进行投票
  • fn remove_voter(origin)

    • 去掉自己投票者的角色,这样可以移除掉锁仓币上的锁,要回锁仓币
  • fn report_defunct_voter(origin,target: ::Source)

    • 将目标投票者报告,说它是一个死的投票者。一个死的投票者定义:
      • 一个投票者现在的提交提票都是无效的,例如其投票的候选人不再是候选人,或者不是一个活跃的成员。
  • fn submit_candidacy(origin)

    • 将某个人自己提名为候选人。候选人将获得如下权利和义务:
      • 锁定候选存款
      • 赢得选举成员议员,拿回质押币
      • 成为候选替补
  • fn remove_member(origin,who: ::Source)

    • Root自己直接移除某个议员,直接生效
      • 如果有一个候选替补是可行的,其最佳的候选替补替换,否则,开启新的选举轮次
  • fn do_phragmen()

    • phragmen选举
      • 调用 ChangeMembers来改变议员集合

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