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:
- Pacemaker::new: creates a fresh instance of the
Pacemaker
, - Pacemaker::view_info: queries the Pacemaker for
ViewInfo
, which can be used to determine whether the view should be updated, - Pacemaker::tick: updates the internal state of the Pacemaker and broadcasts a message if needed in response to a time measurement,
- Pacemaker::on_receive_msg: updates the
PacemakerState
and possibly the block tree, as well as broadcasts messages, in response to a receivedPacemakerMessage
.
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>
impl<N: Network> Pacemaker<N>
sourcepub(crate) fn new(
config: PacemakerConfiguration,
sender: SenderHandle<N>,
init_view: ViewNumber,
init_validator_set_state: &ValidatorSetState,
event_publisher: Option<Sender<Event>>,
) -> Result<Self, PacemakerError>
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.
sourcepub(crate) fn tick<K: KVStore>(
&mut self,
block_tree: &BlockTreeSingleton<K>,
) -> Result<(), PacemakerError>
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:
- If it is an epoch-change view, then its deadline should be extended, and a timeout vote should be broadcasted.
- 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.
sourcepub(crate) fn on_receive_msg<K: KVStore>(
&mut self,
msg: PacemakerMessage,
origin: &VerifyingKey,
block_tree: &mut BlockTreeSingleton<K>,
) -> Result<(), PacemakerError>
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.
sourcefn on_receive_timeout_vote<K: KVStore>(
&mut self,
timeout_vote: TimeoutVote,
signer: &VerifyingKey,
block_tree: &mut BlockTreeSingleton<K>,
) -> Result<(), PacemakerError>
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.
sourcefn on_receive_advance_view<K: KVStore>(
&mut self,
advance_view: AdvanceView,
origin: &VerifyingKey,
block_tree: &mut BlockTreeSingleton<K>,
) -> Result<(), PacemakerError>
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.
sourcefn update_view(
&mut self,
next_view: ViewNumber,
validator_set_state: &ValidatorSetState,
) -> Result<(), PacemakerError>
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.
sourcefn extend_view(&mut self) -> Result<(), ExtendViewError>
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.