Exonum network consists of full nodes connected via peer-to-peer connections, and light clients. Full nodes communicate with each other using Exonum binary serialization format over TCP, and clients interact with full nodes via REST service interface.
Full nodes store the entire contents of the blockchain. All the full nodes are authenticated with public-key cryptography. Full nodes are further subdivided into 2 categories:
- Auditors replicate the entire contents of the blockchain. They can generate new transactions, but cannot choose which transactions should be committed (i.e., cannot generate new blocks)
- Validators exchange consensus messages with each other to reach consensus and add new blocks into the blockchain. Validators receive transactions, verify them, and include into a new block. The list of the validators is restricted by network maintainers, and normally should consist of 4–15 nodes
See separate article for more details on light clients.
Light clients represent clients in the client-server paradigm; they connect to full nodes for several purposes:
- to retrieve information they are interested in from the blockchain
- to subscribe to block commit events and be aware of every new accepted block
- to send transactions.
Exonum also provides a “proofs mechanism”, based on cryptographic commitments via Merkle / Merkle Patricia trees. This mechanism enables light clients to verify that a response from the full node has been really authorized by a supermajority of validators.
Peer-to-Peer Full Node Network
Full nodes use the Exonum binary serialization format over TCP to communicate with each other. The Tokio library is used for event multiplexing. Each node has an event loop, through which the node receives events about new messages from the external network, timeouts, and new transactions received via REST API.
Messages exchanged by full nodes include consensus messages and transactions.
A node broadcasts transactions obtained via API or created by the node itself, but does not broadcast transactions received from other nodes (via broadcasting or requests mechanism).
Consensus Messages and Requests
Validators generate and process consensus messages as specified
by the consensus algorithm.
Auditor nodes are set not to receive consensus messages (
Precommit) when they are broadcast by the validators.
On establishing a P2P connection, nodes exchange
in which a node indicates its public key. The
Connect message also contains
the public IP
address of the node. Each node stores all received
Connect messages in
the list of known peers. As soon as a handshake is reached (the
message is received and successfully processed) from both sides, the nodes begin
to exchange messages.
listen_address is the address where each node in the network accepts
connections from other peers.
Each node regularly sends
to a random known node with the timeout
peers_timeout defined in the
In response, the addressee sends its
list of known peers. Thus, it is enough to connect to one node at the start and
after some time it will be possible to collect
Connect messages from the
At the same time, the initial list of addresses, where other full nodes may
be specified, is defined in the
connect_list) of the node. This list is used to discover
the initial set of peers on the node start up. If some node changes its address,
then through peer discovery mechanism a new address becomes known to
all other nodes in some time.
Meanwhile, the addresses in the
connect_list may be specified both as host
names and IP addresses.
Communication with Light Clients
Light clients use JSON serialization to interact with full nodes via service endpoints. Full nodes receive transactions from light clients via POST requests, and light clients get info from full nodes via GET requests. Transactions from light clients are authenticated with the help of signatures, which are the part of JSON serialization of transactions. Read requests are generally not authenticated.
API endpoints for a particular service are defined via
All service endpoints are prefixed with
service_name is a string service identifier. This identifier needs
to be unique within a specific Exonum blockchain.
There is no unified format for naming endpoints (e.g., passing parameters for GET endpoints via path components and/or query parameters). Thus, services need to use best practices for REST services.
The configuration update service defines the following endpoints among others:
Looks up the global configuration by its hash
Proposes new configuration of the service
Note that both endpoints are prefixed with
prefix as specified above (an additional common prefix
v1 is used for
versioning). The POST endpoint consumes urlencoded JSON representation
of the corresponding service transaction, as it can be inferred from the
semantics of POST requests. The GET endpoint consumes
which is specified as a part of the URL path.