pub trait Blockchain {
type Validator: Validator;
type ValidatorSet: ?Sized + ValidatorSet<Validator = Self::Validator>;
type SignatureScheme: ?Sized + SignatureScheme<Validator = Self::Validator>;
type Genesis: AsRef<[u8]>;
type Block: Block;
type BlockProposal: Future<Output = Self::Block>;
// Required methods
fn genesis(&self) -> &Self::Genesis;
fn validator_set(&self) -> &Self::ValidatorSet;
fn signature_scheme(&self) -> &Self::SignatureScheme;
fn validate(
&self,
proposer: Self::Validator,
block: &Self::Block,
) -> impl Send + Future<Output = Result<(), InvalidBlock>>;
fn add_block(
&mut self,
block: Self::Block,
commit: CommitFor<Self>,
) -> impl Send + Future<Output = Self::BlockProposal>;
fn missed_proposal(&self, proposer: Self::Validator);
fn slash(
&self,
validator: Self::Validator,
slash_reason: SlashReasonFor<Self>,
);
}Expand description
A view of the application layer’s blockchain.
Required Associated Types§
Sourcetype Validator: Validator
type Validator: Validator
The type used to identify validators.
It is RECOMMENDED to use u16 to identify validators.
Sourcetype ValidatorSet: ?Sized + ValidatorSet<Validator = Self::Validator>
type ValidatorSet: ?Sized + ValidatorSet<Validator = Self::Validator>
The type used to define the validator set.
Sourcetype SignatureScheme: ?Sized + SignatureScheme<Validator = Self::Validator>
type SignatureScheme: ?Sized + SignatureScheme<Validator = Self::Validator>
The signature scheme used by validators.
Sourcetype Genesis: AsRef<[u8]>
type Genesis: AsRef<[u8]>
The type used to represent the genesis of this blockchain.
This DOES NOT need to satisfy any cryptographic binding properties and is solely used for
domain-separation purposes. The slice this may be taken as a reference to MUST be consistent
across calls and MUST have a length less than or equal to u8::MAX.
Sourcetype BlockProposal: Future<Output = Self::Block>
type BlockProposal: Future<Output = Self::Block>
The future for a block proposal.
This allows the proposal to not be immediately ready, such as if the blockchain is still
syncing, where this future will be occasionally polled (likely infrequently) for if the
proposal is ready. It is RECOMMENDED to literally instantiate it with
[futures_channel::oneshot::Receiver] or similar.
Required Methods§
Sourcefn genesis(&self) -> &Self::Genesis
fn genesis(&self) -> &Self::Genesis
The genesis ID for this blockchain.
This MUST be consistent for the lifetime of this blockchain and unique across blockchains.
Sourcefn validator_set(&self) -> &Self::ValidatorSet
fn validator_set(&self) -> &Self::ValidatorSet
The validator set’s definition.
This MUST be consistent for the lifetime of this blockchain.
Sourcefn signature_scheme(&self) -> &Self::SignatureScheme
fn signature_scheme(&self) -> &Self::SignatureScheme
The signature scheme for this blockchain.
Sourcefn validate(
&self,
proposer: Self::Validator,
block: &Self::Block,
) -> impl Send + Future<Output = Result<(), InvalidBlock>>
fn validate( &self, proposer: Self::Validator, block: &Self::Block, ) -> impl Send + Future<Output = Result<(), InvalidBlock>>
Validate a block.
This SHOULD NOT cause any mutations to the blockchain. This solely validates a potential candidate with minimal context passed and no call pattern guaranteed. The proposer is specified in case the blockchain wishes to record a slash for this block, if it is fundamentally invalid.
This DOES NOT have to be cancel-safe.
Sourcefn add_block(
&mut self,
block: Self::Block,
commit: CommitFor<Self>,
) -> impl Send + Future<Output = Self::BlockProposal>
fn add_block( &mut self, block: Self::Block, commit: CommitFor<Self>, ) -> impl Send + Future<Output = Self::BlockProposal>
Add a block, returning a future for the proposal for the next block.
It’s possible a block, which was never validated or even failed validation, may be passed here if a supermajority of validators did consider it valid and created a verified commit for it. This deviates from the paper which will have a local node refuse to decide on a block it considers invalid. This library acknowledges the validators did decide on it, leaving handling of it to the application layer, and outside of this scope. If this block is invalid, it’s a break in the assumptions required for Tendermint’s soundness.
The proposal for the next block is returned as a Future. This allows the proposal to not
be ready yet, such as if the blockchain is still syncing, where this future will be
occasionally polled (likely infrequently) for if the proposal is ready. It likely SHOULD be
literally instantiated with [futures_channel::oneshot::Receiver] or similar.
This MAY be called multiple times if the process reboots before the Tendermint process commits its advanced state. The underlying blockchain MUST be able to handle being asked to add a block which it already added.
This DOES NOT have to be cancel-safe.
Sourcefn missed_proposal(&self, proposer: Self::Validator)
fn missed_proposal(&self, proposer: Self::Validator)
Record a missed proposal.
This is a non-async function as this is expected to be implemented in a non-blocking
fashion as to not hold up the consensus process.
A missed proposal is LIKELY something which should cause the validator to be slashed. However, there is no evidence for a missed proposal as it may have never been sent, or may have simply not been received by the local view (which may be the one faulty). For this reason, it’s explicitly distinguished from a slash.
Sourcefn slash(&self, validator: Self::Validator, slash_reason: SlashReasonFor<Self>)
fn slash(&self, validator: Self::Validator, slash_reason: SlashReasonFor<Self>)
Slash a validator.
This is a non-async function as this is expected to be implemented in a non-blocking
fashion as to not hold up the consensus process.
The actual recording of this slash and its interpretation is left entirely to the application layer. All slashes have the necessary evidence and can be verified by this library.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".