> For the complete documentation index, see [llms.txt](https://ethernal-2.gitbook.io/blade/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ethernal-2.gitbook.io/blade/detailed-design/synchronization.md).

# Synchronization

The fundamental objective of each participant, i.e. node, in a blockchain network is to find a sequence of cryptographically linked blocks that, according to a specific parameter (usually the number of blocks), is considered the currently accepted history at a given point in time. This chain is commonly referred to as the **canonical chain**. Various optimization and protection challenges arise in this context.

It is necessary to devise such a mechanism that, alongside an efficient defense against DoS (i.e., denial of service) and Eclipse attacks, will allow a node, regardless of how far behind it is, to align relatively quickly with all other (honest) participants in the network. The implementation is significantly influenced by the way new blocks are generated. Since the Blade system is based on the IBFT 2.0 consensus protocol and immediate finality, there is no need to take into account potential forks and reorganizations. Synchronization, alongside correctly implemented consensus rules, is of essential importance for the meaningful operation of every node.

<figure><img src="/files/k8NHFmeeYaf3YrWHV6rB" alt=""><figcaption><p>Components of the Synchronization Process</p></figcaption></figure>

The entire synchronization process is encapsulated within the `Syncer` object and the execution of its methods. As depicted in the class diagram, this object is a component of `Polybft`, initialized by invoking the `newSyncer()` method during node startup. Upon calling it, various fields of the `Syncer` object are set, including the most important ones: `peerMap`, `syncPeerService`, and `syncPeerClient`. In the context of synchronization, communication between nodes is organized so that each node establishes gRPC service through which other peers can send requests, made by `syncPeerService`. On the other hand, the core of the synchronization logic is implemented inside the `syncPeerClient`. It establishes the foundation for successful synchronization. Finally, as the name suggests, `peerMap` provides insight into the states of peers currently connected to the node. With the state of the node we denote the sequence number of the last block that a peer node has.

After completion of the initialization process, the `Syncer` starts up. This is done as the first step during the start of `Polybft` by calling the `Syncer`'s `Start()` method. Its role is to launch all previously initialized components, as well as collect the current states of all connected peers. The first to be started is `syncPeerClient`.

As mentioned earlier, the `syncPeerClient` provides the foundation for successful synchronization. The first thing that starts within it is the gossip algorithm by calling the `StartGossip` method (this algorithm is exclusively related to blocks, not to transactions). When the method is called, a new topic is registered within the network layer with an appropriate message of the `SyncPeerStatus` type assigned, and then a subscription is made. A node determines which messages to send to each of its connected peers based on their subscriptions. During the subscription, a handler function is defined. It is called on the arrival of a message for the specified topic. In the case of synchronization, the function is checking the validity of the message and its origin, and if everything is fine, it forwards information to the `peerStatusUpdateCh` channel, indicating that a particular node has changed its status. This information includes the ID of the nodes, its new status (the new sequence number of the last block), and the distance to that peer.

In addition to running the gossip algorithm, two other things are started within the client. The first refers to the processing of a new block in the blockchain (`startNewBlockProcess` method). Specifically, if the state of the node's blockchain changes, within this method, a new `SyncPeerStatus` message will be sent to all peers who have subscribed to the topic for synchronization. The second thing that starts is the mechanism for monitoring the connection status of the peers (`startPeerEventProcess` method). Within the given method, upon the appearance or departure of a peer, certain information about it is sent to the `peerConnectionUpdateCh` channel.

Once the client-side synchronization of the node (`syncPeerClient`) is initiated, it is necessary to also activate the server-side (`syncPeerService`). As previously mentioned, this is a gRPC server that facilitates seamless and rapid communication between peers. We will not go into the details of the starting and processing of the gRPC server.

Upon successful completion of the aforementioned steps, the next phase of starting `Syncer` involves initializing the peer map through the `initializePeerMap()` method. It is important to note that this initialization is a one-time action during the node startup. Once the initialization of the map is complete, it is only updated dynamically based on the signals received from the `peerStatusUpdateCh` and `peerConnectionUpdateCh` channels. The peer map initialization process itself is relatively straightforward, entailing the dispatch of queries to each peer requesting their current state in terms of the sequence number of the last block. Subsequently, the peer map is populated, utilizing the peer's ID as the key and its corresponding state as the assigned value.

The final two things that are realized when starting `Syncer`, that is, in its `Start()` method, are related to activation of the mechanism for updating the previously mentioned map. This is carried out through the `startPeerStatusUpdateProcess` and `startPeerConnectionEventProcess` methods of the `Syncer` object. The first has a role to listen on the `peerStatusUpdateCh` channel and, upon the signal's appearance, update the existing map with the new state of the corresponding peer. Additionally, a signal is sent to the `newStatusCh` channel (the role of this channel will be explained further). The second method is responsible for listening on the `peerConnectionUpdateCh` channel. Upon the emergence of a new peer, it sends a request for the peer’s status and adds the new peer to the map (the signal is also sent to the `newStatusCh` channel). In a case of disconnection, the method removes the corresponding peer from the map.

After the successful startup of the `Syncer` synchronization begins. This is achieved by invoking its `Sync` method, again from within `Polybft`. The synchronization process itself is relatively straightforward. It revolves around waiting on the `newStatusCh` channel and upon the signal's appearance, searching for the best peer from the peer map. The best peer is the one with the best status, that is, the one with the highest last block. In a case where two peers share the same status, the distances are considered, and the closer peer is selected. If the best peer has a lower block height than the current node, the process is halted, and the node awaits the next signal on the `newStatusCh` channel. Otherwise, the process proceeds to retrieve blocks from the chosen peer. This is accomplished by invoking the `bulkSyncWithPeer()` method. Within this method, a connection stream is established between the node and the peer, where blocks arrive one after another. As each block arrives, it undergoes validation, and if successful, it is recorded in the blockchain. If any block fails validation, the process halts, the peer is marked as one to avoid further synchronization, and the node returns to waiting on the `newStatusCh` channel.

The entire synchronization process is illustrated through a sequential diagram below.

<figure><img src="/files/xOawBkfFrY0G8Lh2bczE" alt=""><figcaption><p>Synchronization Process Sequence Diagram</p></figcaption></figure>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ethernal-2.gitbook.io/blade/detailed-design/synchronization.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
