pub trait ValidatorSet {
type Validator: Validator;
// Required methods
fn total_weight(&self) -> NonZero<u16>;
fn validators(&self) -> impl IntoIterator<Item = &Self::Validator>;
fn weight(&self, validator: &Self::Validator) -> Option<NonZero<u16>>;
fn proposer(
&self,
block_number: BlockNumber,
round_number: RoundNumber,
) -> Self::Validator;
// Provided methods
fn threshold(&self) -> u16 { ... }
fn fault_threshold(&self) -> u16 { ... }
}Expand description
The set of validators
Required Associated Types§
Required Methods§
Sourcefn total_weight(&self) -> NonZero<u16>
fn total_weight(&self) -> NonZero<u16>
The total weight of all validators.
If this method is incorrect, the Tendermint process MAY panic or be otherwise incorrect.
Sourcefn validators(&self) -> impl IntoIterator<Item = &Self::Validator>
fn validators(&self) -> impl IntoIterator<Item = &Self::Validator>
An iterator over every validator.
The validators MUST be consistent for the lifetime of this blockchain. However, the order they’re yielded in DOES NOT have to be stable. Every validator MUST have weight in the consensus process.
If this method is incorrect, the Tendermint process MAY panic or be otherwise incorrect.
Sourcefn weight(&self, validator: &Self::Validator) -> Option<NonZero<u16>>
fn weight(&self, validator: &Self::Validator) -> Option<NonZero<u16>>
The weight for a specific validator.
This MUST be consistent for the lifetime of this blockchain.
If this method is incorrect, the Tendermint process MAY panic or be otherwise incorrect.
Sourcefn proposer(
&self,
block_number: BlockNumber,
round_number: RoundNumber,
) -> Self::Validator
fn proposer( &self, block_number: BlockNumber, round_number: RoundNumber, ) -> Self::Validator
The proposer for this block and round number.
This MUST be deterministic to these two arguments, block_number and round_number, and
should presumably be a weighted round robin.
Provided Methods§
Sourcefn threshold(&self) -> u16
fn threshold(&self) -> u16
The threshold of weight needed for consensus.
This MUST return a value equal to ((self.total_weight() * 2) / 3) + 1, as the provided
implementation does.
Sourcefn fault_threshold(&self) -> u16
fn fault_threshold(&self) -> u16
The threshold of weight which may be faulty.
This MUST return a value equal to self.total_weight() - self.threshold(), as the provided
implementation does.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".
Implementations on Foreign Types§
Source§impl<V: ?Sized + ValidatorSet> ValidatorSet for &V
impl<V: ?Sized + ValidatorSet> ValidatorSet for &V
type Validator = <V as ValidatorSet>::Validator
fn total_weight(&self) -> NonZero<u16>
fn validators(&self) -> impl IntoIterator<Item = &Self::Validator>
fn weight(&self, validator: &Self::Validator) -> Option<NonZero<u16>>
fn proposer( &self, block_number: BlockNumber, round_number: RoundNumber, ) -> Self::Validator
Source§impl<V: PartialOrd + Ord + Validator, H: BuildHasher> ValidatorSet for HashMap<V, NonZero<u16>, H>
Available on crate feature std only.
impl<V: PartialOrd + Ord + Validator, H: BuildHasher> ValidatorSet for HashMap<V, NonZero<u16>, H>
std only.Source§fn total_weight(&self) -> NonZero<u16>
fn total_weight(&self) -> NonZero<u16>
This MAY panic or be incorrect if the values’ sum is zero or is not representable in a
u16.
Source§fn proposer(
&self,
block_number: BlockNumber,
round_number: RoundNumber,
) -> Self::Validator
fn proposer( &self, block_number: BlockNumber, round_number: RoundNumber, ) -> Self::Validator
This implements a weighted round robin with the validators ordered by the ordinality of
their IDs. This MAY run in time superlinear to the amount of validators, despite
expecting this to be called upon every block proposal. This MAY only make sense for
small validator sets accordingly. For large validator sets, the representation of a
ValidatorSet SHOULD cache the order of the round robin as to allow executing this
function with a lookup.
The round robin is initialized with the block number’s as the starting index, regardless of if prior blocks required multiple rounds to achieve consensus. The round robin is spaced out such that validators with multiple units of weight are not assigned simultaneous slots within a single iteration of the round robin unless they have more weight than all other validators. Each validator’s slots are not guaranteed to be uniformly distributed however and MAY grow in density as the round robin approaches its tail.
To ensure a random distribution, a random coin would be needed, which Tendermint does not
require (nor provide). A bespoke ValidatorSet implementation could make use of one
however. Lacking one, this attempts to provide a slightly more fair distribution (as
detailed above), but this is solely on a best-effort basis.
type Validator = V
fn validators(&self) -> impl IntoIterator<Item = &Self::Validator>
fn weight(&self, validator: &Self::Validator) -> Option<NonZero<u16>>
Source§impl<V: PartialOrd + Ord + Validator> ValidatorSet for BTreeMap<V, NonZero<u16>>
Available on crate feature alloc only.
impl<V: PartialOrd + Ord + Validator> ValidatorSet for BTreeMap<V, NonZero<u16>>
alloc only.Source§fn total_weight(&self) -> NonZero<u16>
fn total_weight(&self) -> NonZero<u16>
This MAY panic or be incorrect if the values’ sum is zero or is not representable in a
u16.
Source§fn proposer(
&self,
block_number: BlockNumber,
round_number: RoundNumber,
) -> Self::Validator
fn proposer( &self, block_number: BlockNumber, round_number: RoundNumber, ) -> Self::Validator
This implements a weighted round robin with the validators ordered by the ordinality of
their IDs. This MAY run in time superlinear to the amount of validators, despite
expecting this to be called upon every block proposal. This MAY only make sense for
small validator sets accordingly. For large validator sets, the representation of a
ValidatorSet SHOULD cache the order of the round robin as to allow executing this
function with a lookup.
The round robin is initialized with the block number’s as the starting index, regardless of if prior blocks required multiple rounds to achieve consensus. The round robin is spaced out such that validators with multiple units of weight are not assigned simultaneous slots within a single iteration of the round robin unless they have more weight than all other validators. Each validator’s slots are not guaranteed to be uniformly distributed however and MAY grow in density as the round robin approaches its tail.
To ensure a random distribution, a random coin would be needed, which Tendermint does not
require (nor provide). A bespoke ValidatorSet implementation could make use of one
however. Lacking one, this attempts to provide a slightly more fair distribution (as
detailed above), but this is solely on a best-effort basis.