pub struct BlockSync<N: Network> { /* private fields */ }Expand description
A struct that keeps track of synchronizing blocks with other nodes.
It generates requests to send to other peers and processes responses to those requests. The struct also keeps track of block locators, which indicate which peers it can fetch blocks from.
§Notes
-
The actual network communication happens in
snarkos_node::Client(for clients and provers) and insnarkos_node_bft::Sync(for validators). -
Validators only sync from other nodes using this struct if they fall behind, e.g., because they experience a network partition. In the common case, validators will generate blocks from the DAG after an anchor certificate has been approved by a supermajority of the committee.
Implementations§
Source§impl<N: Network> BlockSync<N>
impl<N: Network> BlockSync<N>
Sourcepub fn new(ledger: Arc<dyn LedgerService<N>>) -> Self
pub fn new(ledger: Arc<dyn LedgerService<N>>) -> Self
Initializes a new block sync module.
Sourcepub async fn wait_for_peer_update(&self)
pub async fn wait_for_peer_update(&self)
Blocks until something about a peer changes, or block request has been fully processed (either successfully or unsuccessfully).
Used by the outgoing task.
Sourcepub async fn wait_for_block_responses(&self)
pub async fn wait_for_block_responses(&self)
Blocks until there is a new response to a block request.
Used by the incoming task.
Sourcepub fn is_block_synced(&self) -> bool
pub fn is_block_synced(&self) -> bool
Returns true if the node is synced up to the latest block (within the given tolerance).
Sourcepub fn can_block_sync(&self) -> bool
pub fn can_block_sync(&self) -> bool
Returns true if there a blocks to fetch or responses to process.
This will always return true if Self::is_block_synced returns false,
but it can return true when Self::is_block_synced returns true
(due to the latter having a tolerance of one block).
Sourcepub fn num_blocks_behind(&self) -> Option<u32>
pub fn num_blocks_behind(&self) -> Option<u32>
Returns the number of blocks the node is behind the greatest peer height,
or None if no peers are connected yet.
Sourcepub fn greatest_peer_block_height(&self) -> Option<u32>
pub fn greatest_peer_block_height(&self) -> Option<u32>
Returns the greatest block height of any connected peer.
Sourcepub fn get_sync_height(&self) -> u32
pub fn get_sync_height(&self) -> u32
Returns the current sync height of this node. The sync height is always greater or equal to the ledger height.
Sourcepub fn num_outstanding_block_requests(&self) -> usize
pub fn num_outstanding_block_requests(&self) -> usize
Returns the number of blocks we requested from peers, but have not received yet.
Sourcepub fn num_total_block_requests(&self) -> usize
pub fn num_total_block_requests(&self) -> usize
The total number of block request, including the ones that have been answered already but not processed yet.
pub fn get_peer_heights(&self) -> HashMap<SocketAddr, u32>
pub fn get_block_requests_info(&self) -> BTreeMap<u32, BlockRequestInfo>
Sourcepub fn get_block_requests_summary(&self) -> BlockRequestsSummary
pub fn get_block_requests_summary(&self) -> BlockRequestsSummary
Returns a summary of all in-flight requests.
pub fn get_sync_speed(&self) -> f64
Source§impl<N: Network> BlockSync<N>
impl<N: Network> BlockSync<N>
Sourcepub fn get_block_locators(&self) -> Result<BlockLocators<N>>
pub fn get_block_locators(&self) -> Result<BlockLocators<N>>
Returns the block locators.
Sourcepub fn has_pending_responses(&self) -> bool
pub fn has_pending_responses(&self) -> bool
Returns true if there are pending responses to block requests that need to be processed.
Sourcepub async fn send_block_requests<C: CommunicationService>(
&self,
communication: &C,
sync_peers: &IndexMap<SocketAddr, BlockLocators<N>>,
requests: &[(u32, PrepareSyncRequest<N>)],
) -> bool
pub async fn send_block_requests<C: CommunicationService>( &self, communication: &C, sync_peers: &IndexMap<SocketAddr, BlockLocators<N>>, requests: &[(u32, PrepareSyncRequest<N>)], ) -> bool
Send a batch of block requests.
Sourcepub fn insert_block_responses(
&self,
peer_ip: SocketAddr,
blocks: Vec<Block<N>>,
) -> Result<()>
pub fn insert_block_responses( &self, peer_ip: SocketAddr, blocks: Vec<Block<N>>, ) -> Result<()>
Inserts a new block response from the given peer IP.
Returns an error if the block was malformed, or we already received a different block for this height. This function also removes all block requests from the given peer IP on failure.
Note, that this only queues the response. After this, you most likely want to call Self::try_advancing_block_synchronization.
Sourcepub fn peek_next_block(&self, next_height: u32) -> Option<Block<N>>
pub fn peek_next_block(&self, next_height: u32) -> Option<Block<N>>
Returns the next block for the given next_height if the request is complete,
or None otherwise. This does not remove the block from the responses map.
Sourcepub async fn try_advancing_block_synchronization(&self) -> Result<bool>
pub async fn try_advancing_block_synchronization(&self) -> Result<bool>
Attempts to advance synchronization by processing completed block responses.
Returns true, if new blocks were added to the ledger.
§Usage
This is only called in [Client::try_block_sync] and should not be called concurrently by multiple tasks.
Validators do not call this function, and instead invoke
[snarkos_node_bft::Sync::try_advancing_block_synchronization] which also updates the BFT state.
Source§impl<N: Network> BlockSync<N>
impl<N: Network> BlockSync<N>
Sourcepub fn find_sync_peers(&self) -> Option<(IndexMap<SocketAddr, u32>, u32)>
pub fn find_sync_peers(&self) -> Option<(IndexMap<SocketAddr, u32>, u32)>
Returns the sync peers with their latest heights, and their minimum common ancestor, if the node can sync. This function returns peers that are consistent with each other, and have a block height that is greater than the ledger height of this node.
§Locking
This will read-lock common_ancestors and sync_state, but not at the same time.
Sourcepub fn update_peer_locators(
&self,
peer_ip: SocketAddr,
locators: &BlockLocators<N>,
) -> Result<()>
pub fn update_peer_locators( &self, peer_ip: SocketAddr, locators: &BlockLocators<N>, ) -> Result<()>
Updates the block locators and common ancestors for the given peer IP.
This function does not need to check that the block locators are well-formed,
because that is already done in BlockLocators::new(), as noted in BlockLocators.
This function does not check that the block locators are consistent with the peer’s previous block locators or other peers’ block locators.
Sourcepub fn remove_peer(&self, peer_ip: &SocketAddr)
pub fn remove_peer(&self, peer_ip: &SocketAddr)
TODO (howardwu): Remove the common_ancestor entry. But check that this is safe
(that we don’t rely upon it for safety when we re-connect with the same peer).
Removes the peer from the sync pool, if they exist.
Source§impl<N: Network> BlockSync<N>
impl<N: Network> BlockSync<N>
Sourcepub fn prepare_block_requests(&self) -> BlockRequestBatch<N>
pub fn prepare_block_requests(&self) -> BlockRequestBatch<N>
Returns a list of block requests and the sync peers, if the node needs to sync.
You usually want to call remove_timed_out_block_requests before invoking this function.
§Concurrency
This should be called by at most one task at a time.
§Usage
- For validators, the primary spawns one task that periodically calls
bft::Sync::try_block_sync. There is no possibility of multiple calls to it at a time. - For clients,
Client::initialize_syncalso spawns exactly one task that periodically calls this function. - Provers do not call this function.
Sourcepub fn count_request_completed(&self)
pub fn count_request_completed(&self)
Should only be called by validators when they successfully process a block request. (for other nodes this will be automatically called internally)
TODO(kaimast): remove this public function once the sync logic is fully unified BlockSync.
Sourcepub fn set_sync_height(&self, new_height: u32)
pub fn set_sync_height(&self, new_height: u32)
Set the sync height to a the given value.
This is a no-op if new_height is equal or less to the current sync height.
Sourcepub fn remove_block_response(&self, height: u32)
pub fn remove_block_response(&self, height: u32)
Removes the block request and response for the given height
This may only be called after peek_next_block, which checked if the request for the given height was complete.
Precondition: This may only be called after peek_next_block has returned Some,
which has checked if the request for the given height is complete
and there is a block with the given height in the responses map.
Sourcepub fn handle_block_request_timeouts<P: PeerPoolHandling<N>>(
&self,
peer_pool_handler: &P,
) -> Option<BlockRequestBatch<N>>
pub fn handle_block_request_timeouts<P: PeerPoolHandling<N>>( &self, peer_pool_handler: &P, ) -> Option<BlockRequestBatch<N>>
Removes block requests that have timed out, i.e, requests we sent that did not receive a response in time.
This removes the corresponding block responses and returns the set of peers/addresses that timed out. It will ask the peer pool handling service to ban any timed-out peers.
Finally, it will return a set of new of block requests that replaced the timed-out requests (if needed).
Auto Trait Implementations§
impl<N> !Freeze for BlockSync<N>
impl<N> !RefUnwindSafe for BlockSync<N>
impl<N> Send for BlockSync<N>
impl<N> Sync for BlockSync<N>
impl<N> Unpin for BlockSync<N>
impl<N> !UnwindSafe for BlockSync<N>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more