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.
pub async fn wait_for_update(&self)
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.
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_sync
also spawns exactly one task that periodically calls this function. - Provers do not call this function.
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<C: CommunicationService>(
&self,
communication: &C,
) -> Option<BlockRequestBatch<N>>
pub fn handle_block_request_timeouts<C: CommunicationService>( &self, communication: &C, ) -> 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 communication 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