显示包…
2 个稳定版本
2.0.2 | 2021年4月3日 |
---|---|
2.0.0 | 2021年4月2日 |
#118 in #tetcoin
335KB
7.5K SLoC
election-providers
lib.rs
:
提供选举功能的基本特性。
该包提供了两个特性,可以交互以在 FRAME 等包中启用可扩展的选举功能。
能够提供选举功能的某物将实现 ElectionProvider
,同时需要一个相关的 ElectionProvider::DataProvider
,这需要由实现 ElectionDataProvider
的实体来满足。通常,数据提供者是 选举的接收者,从而产生如下所示的图
ElectionDataProvider
<------------------------------------------+
| |
v |
+-----+----+ +------+---+
| | | |
pallet-do-election | | | | pallet-needs-election
| | | |
| | | |
+-----+----+ +------+---+
| ^
| |
+------------------------------------------+
ElectionProvider
也有可能是一个第三方包(C)向选举提供者(B)提供选举数据,然后选举提供者(B)将选举结果传递给另一个包(A)。
选举类型
通常,存在两种类型的选举
- 无状态:提供选举数据,选举结果立即准备好。
- 有状态:提前查询选举数据,选举结果可能在未来的几个块内准备好。
为了在同一个特性中容纳这两种类型的选举,特性倾向于 有状态选举,因为它比无状态选举更通用。这就是为什么 ElectionProvider::elect
没有参数。所有值和类型参数必须由 ElectionDataProvider
特性提供,即使选举立即发生。
选举数据
与选举相关的数据,本质上是指ElectionDataProvider
必须传达的内容如下
- 选民列表,以及他们的利益。
- 目标列表(即候选人)。
- 希望当选的目标数量(即赢家)
除此之外,ElectionDataProvider
还应该暗示ElectionProvider
下次选举可能发生的时间(ElectionDataProvider::next_election_prediction
)。无状态的选举提供者可能会忽略这一点。有状态的选举提供者可以使用它来提前准备选举结果。
尽管如此,ElectionProvider
不应该依赖于这一点,并最好也提供一些备用选举方式,以防在太早的时候调用elect
。
示例
type AccountId = u64;
type Balance = u64;
type BlockNumber = u32;
mod data_provider {
use super::*;
pub trait Config: Sized {
type ElectionProvider: ElectionProvider<
AccountId,
BlockNumber,
DataProvider = Module<Self>,
>;
}
pub struct Module<T: Config>(std::marker::PhantomData<T>);
impl<T: Config> ElectionDataProvider<AccountId, BlockNumber> for Module<T> {
fn desired_targets() -> u32 {
1
}
fn voters() -> Vec<(AccountId, VoteWeight, Vec<AccountId>)> {
Default::default()
}
fn targets() -> Vec<AccountId> {
vec![10, 20, 30]
}
fn next_election_prediction(now: BlockNumber) -> BlockNumber {
0
}
}
}
mod generic_election_provider {
use super::*;
pub struct GenericElectionProvider<T: Config>(std::marker::PhantomData<T>);
pub trait Config {
type DataProvider: ElectionDataProvider<AccountId, BlockNumber>;
}
impl<T: Config> ElectionProvider<AccountId, BlockNumber> for GenericElectionProvider<T> {
type Error = ();
type DataProvider = T::DataProvider;
fn elect() -> Result<Supports<AccountId>, Self::Error> {
Self::DataProvider::targets()
.first()
.map(|winner| vec![(*winner, Support::default())])
.ok_or(())
}
}
}
mod runtime {
use super::generic_election_provider;
use super::data_provider;
use super::AccountId;
struct Runtime;
impl generic_election_provider::Config for Runtime {
type DataProvider = data_provider::Module<Runtime>;
}
impl data_provider::Config for Runtime {
type ElectionProvider = generic_election_provider::GenericElectionProvider<Runtime>;
}
}
依赖项
~3–11MB
~126K SLoC