# Peer Discovery in Nervos Network

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](https://cdn.hashnode.com/res/hashnode/image/upload/v1643527590214/sihBLUeaW.png align="left")

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](https://arxiv.org/pdf/1410.6079.pdf)).
    
* 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](https://en.bitcoin.it/wiki/Satoshi_Client_Node_Discovery) 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](https://cdn.hashnode.com/res/hashnode/image/upload/v1643527785185/pXM_0f3pn.png align="left")

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](https://cdn.hashnode.com/res/hashnode/image/upload/v1643527860693/yxurRrA4j.png align="left")

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](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0008-serialization/0008-serialization.md#molecule) as serialized/deserialized format, the schema is as follows:

```rust
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](https://github.com/nervosnetwork/ckb/tree/78fb281317aeaaa8b2621908cda79928ac697df4/network/src/protocols/discovery).

## References

[Nervos CKB: A Common Knowledge Base for Crypto-Economy](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0002-ckb/0002-ckb.md#nervos-ckb-a-common-knowledge-base-for-crypto-economy)  
[CKB Node Discovery RFC](https://github.com/nervosnetwork/rfcs/blob/master/rfcs/0012-node-discovery/0012-node-discovery.md)

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

---

**You might also like:**

* [RVV (RISC-V V Extension): Key to the Efficient On-Chain Cryptography](https://blog.cryptape.com/rvv-risc-v-v-extension-key-to-the-efficient-on-chain-cryptography)
    
* [Omnilock, a Universal Lock that Powers Interoperability](https://blog.cryptape.com/omnilock-a-universal-lock-that-powers-interoperability-1)
    
* [Blockchain Abstraction and Interoperability 2.0](https://blog.cryptape.com/blockchain-abstraction-and-interoperability-20)
