Substrate中scored-pool模块分析
Scored Pool模块,包含一个scored议会成员池,每个实体在池中都能被记分,在议会成员从这个池中选出来的时候,就根据这个池中得分最高的一组实体。没有被记分的实体是不可能成为议会议员的。
要想成为记分池中的一部分,账号下存款是必须的,存款会被返回当实体提现或者其被移除出记分池的时候。
每一个周期,议会成员会更新一次,从积分池中最高一组实体中选出,不管这个最高排名是否发生了变化。T::MembershipChanged::set_members_sorted
将被触发,如果在初始化议会成员组的时候,会触发另外一个方法T::MembershipInitialized::initialize_members
。
在任何时候,都能够体现,从议会成员中退出来,如果这个实体是一个议会成员,结果是从记分池中移除,这个实体会被池中下一个最高记分的候选替换。
公开的方法
-
submit_candidacy
:提交一个候选资格去成为一个议员,需要相应的存款。 -
withdraw_candidacy
:取回候选人资格,可以取回相应的存款。 -
score
:获取某个实体的量化记分。 -
kick
:从积分池中和议会议员中移除某个实体,存款会被退还。 -
change_member_count
:改变候选人进入议会成员。
enum ChangeReceiver {
MembershipInitialized, // 调用 `T::MembershipInitialied`
MembershipChanged, // 应该调用 `T::MembershipChanged`
}
Trait
/// 用于候选人的存款抵押
type Currency: Currency<Self::AccountId> + ReservableCurrency<Self::AccountId>;
/// 给候选人的记分
type Score:
SimpleArithmetic + Clone + Copy + Default + FullCodec + MaybeSerializeDeserialize + Debug;
/// The overarching event type.
type Event: From<Event<Self, I>> + Into<<Self as system::Trait>::Event>;
// 如果一个候选人想要开启选举,其存款是需要抵押保留的. 当候选人被踢掉或者自己提现了,就会退还保留抵押存款
type CandidateDeposit: Get<BalanceOf<Self, I>>;
/// 议会轮换周期
type Period: Get<Self::BlockNumber>;
/// 上面receiver接收到议会成员被初始化的信号
type MembershipInitialized: InitializeMembers<Self::AccountId>;
/// 上面receiver接收到议会成员被更改的信号
type MembershipChanged: ChangeMembers<Self::AccountId>;
/// Allows a configurable origin type to set a score to a candidate in the pool.
type ScoreOrigin: EnsureOrigin<Self::Origin>;
/// 允许Root踢掉某个议会成员
type KickOrigin: EnsureOrigin<Self::Origin>;
Storage
/// 候选人池
Pool get(fn pool) config(): PoolT<T, I>;
/// 候选人Map
CandidateExists get(fn candidate_exists): map T::AccountId => bool;
/// 议会成员Vec
Members get(fn members): Vec<T::AccountId>;
/// 议会成员数量
MemberCount get(fn member_count) config(): u32;
初始化设置
候选人池:
build(|config| {
let mut pool = config.pool.clone();
// reserve balance for each candidate in the pool.
// panicking here is ok, since this just happens one time, pre-genesis.
pool
.iter()
.for_each(|(who, _)| {
T::Currency::reserve(&who, T::CandidateDeposit::get())
.expect("balance too low to create candidacy");
<CandidateExists<T, I>>::insert(who, true);
});
/// Sorts the `Pool` by score in a descending order. Entities which
/// have a score of `None` are sorted to the beginning of the vec.
pool.sort_by_key(|(_, maybe_score)|
Reverse(maybe_score.unwrap_or_default())
);
<Pool<T, I>>::put(&pool);
<Module<T, I>>::refresh_members(pool, ChangeReceiver::MembershipInitialized);
})
Module
- fn on_initialize(n: T::BlockNumber)
- 在议会轮换周期Period,需要调用
refresh_members(pool,ChangeReceiver::MembershipChanged)
方法
- 在议会轮换周期Period,需要调用
- pub fn submit_candidacy(origin)
- 提交候选资格
- pub fn withdraw_candidacy(origin,index: u32)
- 从候选池中取回候选资格
- pub fn kick(origin,dest: <T::Lookup as StaticLookup>::Source,index: u32)
- 提出某个议员从议员集合中
- pub fn score(origin,dest: <T::Lookup as StaticLookup>::Source,index: u32,score: T::Score)
- 给候选池中某个候选人打分
网友评论