hotstuff_rs::pacemaker::protocol

Struct Pacemaker

source
pub(crate) struct Pacemaker<N: Network> {
    config: PacemakerConfiguration,
    state: PacemakerState,
    view_info: ViewInfo,
    sender: SenderHandle<N>,
    event_publisher: Option<Sender<Event>>,
}
Expand description

A Pacemaker protocol for Byzantine View Synchronization inspired by the Lewis-Pye View Synchronization protocol. Its PacemakerState is the authoritative source of information regarding the current view and its leader, and Algorithm should regularly query the Pacemaker for this information (ViewInfo), and propagate the information to hotstuff.

The Pacemaker exposes the following API for use in the Algorithm:

  1. Pacemaker::new: creates a fresh instance of the Pacemaker,
  2. Pacemaker::view_info: queries the Pacemaker for ViewInfo, which can be used to determine whether the view should be updated,
  3. Pacemaker::tick: updates the internal state of the Pacemaker and broadcasts a message if needed in response to a time measurement,
  4. Pacemaker::on_receive_msg: updates the PacemakerState and possibly the block tree, as well as broadcasts messages, in response to a received PacemakerMessage.

If any of these actions fail, a PacemakerError is returned.

Fields§

§config: PacemakerConfiguration§state: PacemakerState§view_info: ViewInfo§sender: SenderHandle<N>§event_publisher: Option<Sender<Event>>

Implementations§

source§

impl<N: Network> Pacemaker<N>

source

pub(crate) fn new( config: PacemakerConfiguration, sender: SenderHandle<N>, init_view: ViewNumber, init_validator_set_state: &ValidatorSetState, event_publisher: Option<Sender<Event>>, ) -> Result<Self, PacemakerError>

Create a new Pacemaker instance.

source

pub(crate) fn view_info(&self) -> &ViewInfo

Query the pacemaker for ViewInfo.

source

pub(crate) fn tick<K: KVStore>( &mut self, block_tree: &BlockTreeSingleton<K>, ) -> Result<(), PacemakerError>

Check the current time (‘clock tick’), and possibly send messages and update the internal state of the pacemaker in response to the ‘clock tick’.

First, in response to a clock tick indicating a view timeout the state can be updated in two ways:

  1. If it is an epoch-change view, then its deadline should be extended, and a timeout vote should be broadcasted.
  2. If it is a not an epoch-change view, then the view should be updated to the subsequent view.

Additionally, tick should check if there is a PC for the current view (whether an epoch-change view or not) available in the block tree, and if so it should broadcast the PC in an advance view message.

It should also check of the validator set state has been updated, and if so it should update the timeout vote collectors accordingly.

source

pub(crate) fn on_receive_msg<K: KVStore>( &mut self, msg: PacemakerMessage, origin: &VerifyingKey, block_tree: &mut BlockTreeSingleton<K>, ) -> Result<(), PacemakerError>

Update the internal state of the pacemaker and possibly the block tree, in response to receiving a PacemakerMessage. Broadcast an AdvanceView message in case a TimeoutCertificate was collected, or in case a valid AdvanceView message was received from a peer.

source

fn on_receive_timeout_vote<K: KVStore>( &mut self, timeout_vote: TimeoutVote, signer: &VerifyingKey, block_tree: &mut BlockTreeSingleton<K>, ) -> Result<(), PacemakerError>

Update the internal state of the pacemaker in response to receiving a TimeoutVote.

If a TimeoutCertificate is collected, the replica should try to update its highest_tc and broadcast the collected TimeoutCertificate. The vote may be rejected if the receiver replica is lagging behind the quorum from which the vote is sent. In such case the replica can use the sender’s highest_tc attached to the vote to move ahead.

§Preconditions

The Timeout Vote may be for any view greater or equal to the current view, but only timeout votes for the current view will be collected.

source

fn on_receive_advance_view<K: KVStore>( &mut self, advance_view: AdvanceView, origin: &VerifyingKey, block_tree: &mut BlockTreeSingleton<K>, ) -> Result<(), PacemakerError>

Update the internal state of the pacemaker and possibly the block tree in response to receiving an AdvanceView message.

§Preconditions

The Advance View message must be for the current or higher view.

source

fn update_view( &mut self, next_view: ViewNumber, validator_set_state: &ValidatorSetState, ) -> Result<(), PacemakerError>

Update the current view to the specified next_view. This may involve setting timeouts for the views of a new epoch, in case the next view is in a future epoch.

This method, by being the unique method used to update the pacemaker ViewInfo, and checking if the next view is greater than the current view, guarantees that views are monotonically increasing.

§Errors

This function should only be called if next_view is greater than the current view. Otherwise, an UpdateViewError will be returned.

source

fn extend_view(&mut self) -> Result<(), ExtendViewError>

Extend the timeout of the current view

§Errors

This function should only be called if the current view is an epoch-change view. Otherwise, an ExtendViewError will be returned.

Auto Trait Implementations§

§

impl<N> Freeze for Pacemaker<N>
where N: Freeze,

§

impl<N> RefUnwindSafe for Pacemaker<N>
where N: RefUnwindSafe,

§

impl<N> Send for Pacemaker<N>

§

impl<N> Sync for Pacemaker<N>
where N: Sync,

§

impl<N> Unpin for Pacemaker<N>
where N: Unpin,

§

impl<N> UnwindSafe for Pacemaker<N>
where N: UnwindSafe,

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, 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.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V