Peer Discovery in Nervos Network

Peer Discovery in Nervos Network

·

6 min read

This article briefly explains how two nodes discover each other in Nervos CKB. First, we will outline the Nervos Network architecture and the three types of nodes and their roles in the network. We will then describe the peer discovery in three different scenarios. Finally, we will demonstrate the data structures of the discovery protocols.

Network Architecture, Nodes and Their Roles

Nervos CKB (Common Knowledge Base) is a Layer 1 blockchain, a decentralized and secure layer that provides common knowledge custody for the network. Common knowledge refers to states that are verified by global consensus. Crypto-assets are one example of common knowledge.

In Nervos, CKB (or Layer 1) and all Layer 2 protocols work together to serve the crypto-economy. Layer 2 processes most transactions, generates and computes (these two terms are interchangeable) new states, while CKB the Layer 1 stores and verifies the states. Layer 2 participants end up submitting newly generated states to the CKB when they deem necessary. If those states pass the corresponding verification performed by CKB nodes, the CKB network stores these states securely in a decentralized peer-to-peer network .

CKB nodes have three types:

  • Mining Nodes: They participate in the CKB Proof-of-Work consensus process. Mining nodes collect new transactions, package them into blocks and produce new blocks.

  • Full Nodes: They verify new blocks and transactions, relay blocks and transactions, and select the chains they consent to fork. They are the verifiers of the network.

  • Light Nodes: They trust full nodes. With minimal resource, they subscribe and store a subset of cells of their interests.

The nodes involved in peer discovery are full nodes.

Peer Discovery in Nervos CKB

Overview

In a decentralized peer-to-peer network, nodes discover each other through discovery protocols. Once two nodes get connected, they share the list of active nodes they know to propagate information across the network. This is how separated nodes discover other peers in the network.

CKB keeps records of known peer nodes in the peer database, located at network/peer_store/addr_manager.db. If the peer database is empty, CKB reads the bootnodes list from the configuration item network.bootnodes in ckb.toml and connects to a random node in the bootnodes list.

After node discovery, CKB uses other protocols, such as Feeler, to determine the accessibility of the target node, the network quality, etc. These topics will be covered in some other articles.

Scenario 1. Bootstrap

Use Default Bootnode Addresses Bootnode addresses represent CKB nodes. They are put in the configuration file ckb.toml for bootstrapping in the node discovery protocol. Bootnodes have a high uptime and sufficient connectivity to other live nodes of the network.

Once the local node has established connections with the bootnodes, these connections will not be closed unless the remote node disconnects. After getting enough addresses, we suggest the local node proactively disconnects from the bootnodes to avoid an overload of these bootnodes.

image.png

Figure 1: The bootstrap stage

After bootstrapping, the local node will send a GetNodes message to other remote nodes if the following conditions are met:

  • The connection is outbound, sent from the local node to the remote node (for resisting fingerprint attack).

  • The version number of the remote node must be higher than the local node (to make sure that the discovery protocol is supported by the remote nodes).

  • The number of addresses currently stored must be less than ADDRESSES_THRESHOLD (by default 1000).

Note: The bootnodes list in configuration file is a default for users convenience not a hardcoded setting. Users could simply replace the default bootnodes with any nodes they like (e.g. a CKB node run by friends) to initiate a fresh new CKB node. The same mechanism is used in Bitcoin.

Scenario 2. GetNodes & Nodes messages

The local node opens an outbound connection towards the discovered remote node and sends a GetNodes message. This message contains the version number of discovery protocol, the quantity of the remote nodes’ addresses requested to fetch, and the listening port of the local node.

After receiving the message, the remote node - the “outbound peer” in Figure 2 below - begins to select the available addresses to include in the Nodes message. When the remote node receives a GetNodes request, it should return a Nodes message if this is the initial reception and the connection is inbound (from the remote node’s perspective), the announce field gets set as false.

image (1).png

Figure 2: Send GetNodes message and message processing

  • announce field in Nodes can help distinguish whether it is a response to a GetNodes request or a broadcast message.

Scenario 3. Announce Connected Nodes

Having received a Nodes message, the local node adds these addresses in the message to the internal address list. It will further broadcast the public IP addresses of the nodes with which it is connected in the Nodes message. The announce field is set true under this scenario.

The broadcast should be done at regular intervals.

image (2).png

Figure 3: Announce connected nodes

The CKB node applies different penalty rules to misbehaving peers based on the Boolean value of announce. These rules are:

  • A node can only send one response message (announce = false)

  • Only the first of the broadcast messages (announce = true) can exceed ANNOUNCE_THRESHOLD (default = 10) to avoid message overload.

  • The number of addresses field of each Node in all Nodes messages should be within MAX_NODE_ADDRESSES (default = 3).

Once a connection is established between two CKB nodes, each node sends a query asking for the active nodes known to the other end, and responds accordingly.

The query stops following the exchange. At regular intervals, the nodes will send information notifying their peers of the active nodes they know.

Data Structure of Discovery Protocols

The discovery messages are the initial exchange between a new node and its peer. It contains three parts. CKB uses Molecule as serialized/deserialized format, the schema is as follows:

union DiscoveryMessage {
    GetNodes,
    Nodes,
}
table GetNodes {
    version: Uint32,
    count: Uint32,
    listen_port: PortOpt,
}
table Nodes {
    announce: Bool;
    items: [Node];
}
table Node {
    node_id: Bytes;
    addresses: [Bytes];
}
  • GetNodes : The query sent from the local node to its peer. This message includes the version, size, and listening port of the local node.

  • version : Discovery protocol version.

  • count : The maximum number of nodes it accepts.

  • listen_port : The public listening port of the local node.

  • Nodes : Message sent from the remote node. It contains the information of the active nodes it knows.

  • announce : Field with false value indicates that it is a response message to GetNodes query; announce field with true value indicates that it is a broadcast message so it needs to broadcast the active nodes it knows to its peer nodes.

For more CKB peer discovery protocol details, see CKB Network Discovery Source Code.

References

Nervos CKB: A Common Knowledge Base for Crypto-Economy
CKB Node Discovery RFC

✍🏻 Written by: Linfeng Qian, Chao Luo, Guozhen Wang, Hsu Chan


You might also like: