The Block Exchange Module is a core component of Codex responsible for peer-to-peer content distribution. It handles the sending and receiving of blocks across the network, enabling efficient data sharing between Codex nodes.
The Block Exchange Protocol uses the following libp2p protocol identifier:
```
/codex/blockexc/1.0.0
```
## Connection Model
The protocol operates over libp2p streams. When a node wants to communicate with a peer:
1. The initiating node dials the peer using the protocol identifier
2. A bidirectional stream is established
3. Both sides can send and receive messages on this stream
4. Messages are encoded using Protocol Buffers
5. The stream remains open for the duration of the exchange session
6. Peers track active connections in a peer context store
The protocol handles peer lifecycle events:
- **Peer Joined**: When a peer connects, it is added to the active peer set
- **Peer Departed**: When a peer disconnects gracefully, its context is cleaned up
- **Peer Dropped**: When a peer connection fails, it is removed from the active set
## Message Format
All messages exchanged between peers use Protocol Buffers encoding.
### Message Structure
```protobuf
message Message {
Wantlist wantlist = 1;
repeated BlockDelivery payload = 3;
repeated BlockPresence blockPresences = 4;
int32 pendingBytes = 5;
AccountMessage account = 6;
StateChannelUpdate payment = 7;
}
```
**Field Descriptions:**
-`wantlist`: Requests for blocks (presence checks or full block requests)
-`payload`: Block deliveries being sent to the peer
-`blockPresences`: Block presence information (have/don't have)
-`pendingBytes`: Number of bytes currently pending delivery to this peer
-`account`: Ethereum account information for receiving payments
-`payment`: Nitro state channel update for micropayments
### Block Addressing
Codex uses a block addressing scheme that supports both simple content-addressed blocks and blocks within Merkle tree structures.
```protobuf
message BlockAddress {
bool leaf = 1;
bytes treeCid = 2; // Present when leaf = true
uint64 index = 3; // Present when leaf = true
bytes cid = 4; // Present when leaf = false
}
```
**Addressing Modes:**
- **Simple Block** (`leaf = false`): Direct CID reference to a standalone content block
- **Tree Block** (`leaf = true`): Reference to a block within a Merkle tree by tree CID and index. The tree may represent either an erasure-coded dataset or a regular uploaded file organized in a tree structure
### WantList
The WantList allows a peer to request blocks or check for block availability.