Consensus

Struct Consensus 

Source
pub struct Consensus<V: ValuePayload + 'static, A: ValidatorAddress + 'static, P: ProposerSelector<A> + Send + Sync + 'static> { /* private fields */ }
Expand description

§Pathfinder consensus engine

This is the main consensus engine for Starknet nodes that implements Byzantine Fault Tolerant (BFT) consensus using the Malachite implementation of Tendermint. It’s generic over validator addresses, consensus values, and proposer selection algorithms, making it suitable for Starknet’s consensus requirements.

§Generic Parameters

  • V: Your consensus value type (must implement ValuePayload)
  • A: Your validator address type (must implement ValidatorAddress)
  • P: Your proposer selector type (must implement ProposerSelector<A>)

§Usage

let config = Config::new(my_address);
let mut consensus = Consensus::new(config);

// Start consensus at a height
consensus.handle_command(ConsensusCommand::StartHeight(height, validator_set));

// Poll for events
while let Some(event) = consensus.next_event().await {
    // Handle events
}

§Custom Proposer Selection

To use a custom proposer selector:

let config = Config::new(my_address);
let custom_selector = WeightedProposerSelector;
let mut consensus = Consensus::with_proposer_selector(config, custom_selector);

§Crash Recovery

The consensus engine supports crash recovery through write-ahead logging:

let validator_sets = Arc::new(StaticValidatorSetProvider::new(validator_set));
let mut consensus = Consensus::recover(config, validator_sets)?;

Implementations§

Source§

impl<V: ValuePayload + 'static, A: ValidatorAddress + 'static, P: ProposerSelector<A> + Send + Sync + 'static> Consensus<V, A, P>

Source

pub fn new(config: Config<A>) -> DefaultConsensus<V, A>

Create a new consensus engine for the current validator.

§Arguments
  • config: The consensus configuration containing validator address, timeouts, and other settings
§Example
let config = Config::new(my_address);
let mut consensus = Consensus::new(config);
Source

pub fn with_proposer_selector<PS: ProposerSelector<A> + Send + Sync + 'static>( config: Config<A>, proposer_selector: PS, ) -> Consensus<V, A, PS>

Create a new consensus engine with a custom proposer selector for this consensus engine.

§Arguments
  • config: The consensus configuration containing validator address, timeouts, and other settings
  • proposer_selector: The proposer selection algorithm to use
§Example
let config = Config::new(my_address);
let custom_selector = WeightedProposerSelector;
let mut consensus = Consensus::with_proposer_selector(config, custom_selector);
Source

pub fn recover<VS: ValidatorSetProvider<A> + 'static>( config: Config<A>, validator_sets: Arc<VS>, highest_committed: Option<u64>, ) -> Result<DefaultConsensus<V, A>>

Recover recent heights from the write-ahead log.

This method is used to recover consensus state after a crash or restart. It reads the write-ahead log and reconstructs the consensus state for all incomplete heights.

§Arguments
  • config: The consensus configuration
  • validator_sets: A provider for validator sets at different heights
  • highest_committed: The highest committed block in main storage
§Example
let validator_sets = Arc::new(StaticValidatorSetProvider::new(validator_set));
let mut consensus = Consensus::recover(config, validator_sets)?;
Source

pub fn recover_with_proposal_selector<VS: ValidatorSetProvider<A> + 'static, PS: ProposerSelector<A> + Send + Sync + 'static>( config: Config<A>, validator_sets: Arc<VS>, proposer_selector: PS, highest_committed: Option<u64>, ) -> Result<Consensus<V, A, PS>>

Recover recent heights from the write-ahead log with a custom proposer selector for this consensus engine.

This method is used to recover consensus state after a crash or restart. It reads the write-ahead log and reconstructs the consensus state for all incomplete heights.

§Arguments
  • config: The consensus configuration
  • validator_sets: A provider for validator sets at different heights
  • proposer_selector: The proposer selection algorithm to use
§Example
let validator_sets = Arc::new(StaticValidatorSetProvider::new(validator_set));
let mut consensus = Consensus::recover(config, validator_sets)?;
Source

pub fn handle_command(&mut self, cmd: ConsensusCommand<V, A>)

Feed a command into the consensus engine.

This method is the primary way to interact with the consensus engine. Commands include starting new heights, submitting proposals, and processing votes.

§Arguments
  • cmd: The command to process
§Example
// Start a new height
consensus.handle_command(ConsensusCommand::StartHeight(height, validator_set));

// Submit a proposal
consensus.handle_command(ConsensusCommand::Proposal(signed_proposal));

// Process a vote
consensus.handle_command(ConsensusCommand::Vote(signed_vote));
Source

pub async fn next_event(&mut self) -> Option<ConsensusEvent<V, A>>

Poll all engines for an event.

This method should be called regularly to process events from the consensus engine. Events include requests for proposals, decisions, gossip messages, and errors.

§Returns

Returns Some(event) if an event is available, or None if no events are ready.

§Example
while let Some(event) = consensus.next_event().await {
    match event {
        ConsensusEvent::RequestProposal { height, round } => {
            // Build and submit a proposal
        }
        ConsensusEvent::Decision { height, value } => {
            // Consensus reached, process the value
        }
        ConsensusEvent::Gossip(message) => {
            // Send message to peers
        }
        ConsensusEvent::Error(error) => {
            // Handle error
        }
    }
}
Source

pub fn is_height_finalized(&self, height: u64) -> bool

Check if a specific height has been finalized (i.e., a decision has been reached)

§Arguments
  • height: The height to check
§Returns

Returns true if the height has been finalized, false otherwise.

§Example
if consensus.is_height_finalized(height) {
    println!("Height {} has been finalized", height);
}
Source

pub fn is_height_active(&self, height: u64) -> bool

Check if a specific height is actively tracked by the consensus engine.

§Arguments
  • height: The height to check
§Returns

Returns true if the height is active, false otherwise.

Source

pub fn max_active_height(&self) -> Option<u64>

Get the maximum height actively being tracked by the consensus engine.

This returns the highest height that consensus is currently working on, which includes incomplete heights that haven’t reached a decision yet. Returns None if there are no actively tracked heights.

Source

pub fn last_decided_height(&self) -> Option<u64>

Get the highest height that consensus has decided on.

This returns the highest height that has a Decision entry, even if that height is no longer actively tracked (e.g., after recovery when it was skipped).

Returns None if no decisions have been made yet.

Auto Trait Implementations§

§

impl<V, A, P> Freeze for Consensus<V, A, P>
where P: Freeze, A: Freeze,

§

impl<V, A, P> !RefUnwindSafe for Consensus<V, A, P>

§

impl<V, A, P> Send for Consensus<V, A, P>

§

impl<V, A, P> !Sync for Consensus<V, A, P>

§

impl<V, A, P> Unpin for Consensus<V, A, P>
where P: Unpin, A: Unpin, V: Unpin,

§

impl<V, A, P> !UnwindSafe for Consensus<V, A, P>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

impl<T> ErasedDestructor for T
where T: 'static,