2️⃣-Peer Protocol
Overview
The current protocol requires a direct connection between two nodes for performing updates, trades, and swaps. This section describes how the connection is set up.
Each node maintains a persistent secp256k1 private key with a corresponding public key, node key for short, which uniquely identifies the node in the network. We recommend only allowing manual resets of the private key, for example by deleting a file or database entry.
An initial handshake is required to establish a secure TCP-based session between two nodes. The default listening TCP port is 8885.
Handshake Protocol
The communication session is established by creating a TCP connection and agreeing on ephemeral key material for further encrypted communication, in addition to utilizing the persistent key for authentication. The process of establishing this session is the “handshake” and is carried out between the “initiator” (the peer that opened the TCP connection) and the “recipient” (the peer that accepted it).
The handshake consists of each side sending the SessionInit
message, and waiting to receive the SessionAck
message back. The first SessionInit
message is expected to be sent by the initiator.
The initiator must know the recipient's identity (node key) in advance. The recipient learns the initiator's identity by receiving the SessionInit
message.
By the end of the handshake, two distinct shared keys are created, one for each side of the communication, to be used to encrypt all messages during the session's lifetime.
Handshake Messages
These messages are used in the initial handshake:
SessionInit Message (0x00)
Once received by the destination node, the message is authenticated as follows:
peer_pub_key
should match the destination node's public keynode_pub_key
should match the sender node expected public key (relevant for the initiator node only since he already knows the recipient node's identity)sign
should be a valid secp256k1 signature over the sha256 hash of a JSON-serialized msg containing fields 3-7
If the fields of the SessionInit
message are valid, the receiver replies with a SessionAck
message. If a SessionAck
message is not received within a reasonable time frame (10 seconds is recommended), the sender may disconnect.
SessionAck Message (0x01)
Once the receiver of the SessionInit
message (Bob) has generated his ECDH keys, he can calculate the shared key by using the ephemeral_pub_key
from the SessionInit
message. Once the SessionAck
message is received by the sender of the SessionInit
message (Alice), she can compute the shared key as well. All future communication from Alice to Bob must be encrypted with aes-256-cbc symmetric encryption using the shared key.
Coordination Messages
These messages are used to maintain the P2P overlay after a session has been established via the initial handshake.
Ping Message (0x04)
In order to allow long-lived TCP connections, both ends keep the TCP connection alive at the application level using Ping
and Pong
messages.
It is recommended to send a Ping
message every 30 seconds.
The sender of a Ping
message may disconnect if a Pong
message is not received within 10 seconds.
Pong Message (0x05)
The Pong
message is sent in response to the Ping
message. It serves to keep the connection alive by explicitly notifying the other end that the receiver is still active.
Disconnecting Message (0x03)
The Disconnecting
message is used to inform a connected peer that a disconnection is imminent and that the peer should disconnect immediately. A well-behaved host that sends a Disconnecting
message allows the peer at least 2 seconds to disconnect before disconnecting itself.
reason
is an optional parameter for specifying one of the following reasons for the disconnection:
Reason | Meaning |
---|---|
| Response stalling |
| Incompatible client protocol version |
| Unexpected identity |
| Forbidden identity update |
| Connected to self |
| Not accepting new connections |
| Banned |
| Already connected |
| Shutdown |
| Malformed version |
| Authentication failure: invalid target node |
| Authentication failure: invalid signature |
| Wire protocol error |
GetNodes Message (0x0a)
The GetNodes
message is used to query a peer for its list of known, reachable OpenDEX nodes.
Nodes Message (0x0b)
The Nodes
message is used to respond to the GetNodes
message.
NodeStateUpdate Message (0x02)
The NodeStateUpdate
message is used to tell a peer about a change in the node state. An example of an update is the removal or addition of a supported trading pair.
Custom types
NodeState type
Address type
LndUris type
Node type
Last updated