Skip to content

Commit 63d8fd0

Browse files
wip: Network specification (#69)
* wip: Network specification * Address comments by Alex S. * Expand sections and add pseudo code * Use same style used for sha256/concat/borsh * move network spec to its own folder Co-authored-by: Bowen Wang <[email protected]>
1 parent e05013e commit 63d8fd0

File tree

5 files changed

+404
-1
lines changed

5 files changed

+404
-1
lines changed

.gitignore

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
/docs
22
.idea
33
.DS_Store
4-
.vscode
4+
.vscode

specs/NetworkSpec/Messages.md

Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
# Messages
2+
3+
All message sent in the network are of type `PeerMessage`. They are encoded using [Borsh](https://borsh.io/) which allows a rich structure, small size and fast encoding/decoding. For details about data structures used as part of the message see the [reference code](https://github.com/nearprotocol/nearcore).
4+
5+
## Encoding
6+
7+
A `PeerMessage` is converted into an array of bytes (`Vec<u8>`) using borsh serialization. An encoded message is conformed by 4 bytes with the length of the serialized `PeerMessage` concatenated with the serialized `PeerMessage`.
8+
9+
Check [Borsh specification](https://github.com/nearprotocol/borsh#specification) details to see how it handles each data structure.
10+
11+
## Data structures
12+
13+
### PeerID
14+
15+
The id of a peer in the network is its [PublicKey](https://github.com/nearprotocol/nearcore/blob/master/core/crypto/src/signature.rs).
16+
17+
```rust
18+
struct PeerId(PublicKey);
19+
```
20+
21+
### PeerInfo
22+
23+
24+
```rust
25+
struct PeerInfo {
26+
id: PeerId,
27+
addr: Option<SocketAddr>,
28+
account_id: Option<AccountId>,
29+
}
30+
```
31+
32+
`PeerInfo` contains relevant information to try to connect to other peer. [`SocketAddr`](https://doc.rust-lang.org/std/net/enum.SocketAddr.html) is a tuple of the form: `IP:port`.
33+
34+
### AccountID
35+
36+
```rust
37+
type AccountId = String;
38+
```
39+
40+
### PeerMessage
41+
42+
```rust
43+
enum PeerMessage {
44+
Handshake(Handshake),
45+
HandshakeFailure(PeerInfo, HandshakeFailureReason),
46+
/// When a failed nonce is used by some peer, this message is sent back as evidence.
47+
LastEdge(Edge),
48+
/// Contains accounts and edge information.
49+
Sync(SyncData),
50+
RequestUpdateNonce(EdgeInfo),
51+
ResponseUpdateNonce(Edge),
52+
PeersRequest,
53+
PeersResponse(Vec<PeerInfo>),
54+
BlockHeadersRequest(Vec<CryptoHash>),
55+
BlockHeaders(Vec<BlockHeader>),
56+
BlockRequest(CryptoHash),
57+
Block(Block),
58+
Transaction(SignedTransaction),
59+
Routed(RoutedMessage),
60+
/// Gracefully disconnect from other peer.
61+
Disconnect,
62+
Challenge(Challenge),
63+
}
64+
```
65+
66+
### AnnounceAccount
67+
68+
Each peer should announce its account
69+
70+
```rust
71+
struct AnnounceAccount {
72+
/// AccountId to be announced.
73+
account_id: AccountId,
74+
/// PeerId from the owner of the account.
75+
peer_id: PeerId,
76+
/// This announcement is only valid for this `epoch`.
77+
epoch_id: EpochId,
78+
/// Signature using AccountId associated secret key.
79+
signature: Signature,
80+
}
81+
```
82+
83+
### Handshake
84+
85+
```rust
86+
struct Handshake {
87+
/// Protocol version.
88+
pub version: u32,
89+
/// Oldest supported protocol version.
90+
pub oldest_supported_version: u32,
91+
/// Sender's peer id.
92+
pub peer_id: PeerId,
93+
/// Receiver's peer id.
94+
pub target_peer_id: PeerId,
95+
/// Sender's listening addr.
96+
pub listen_port: Option<u16>,
97+
/// Peer's chain information.
98+
pub chain_info: PeerChainInfoV2,
99+
/// Info for new edge.
100+
pub edge_info: EdgeInfo,
101+
}
102+
```
103+
104+
<!-- TODO: Make diagram about handshake process, since it is very complex -->
105+
106+
### Edge
107+
108+
```rust
109+
struct Edge {
110+
/// Since edges are not directed `peer0 < peer1` should hold.
111+
peer0: PeerId,
112+
peer1: PeerId,
113+
/// Nonce to keep tracking of the last update on this edge.
114+
nonce: u64,
115+
/// Signature from parties validating the edge. These are signature of the added edge.
116+
signature0: Signature,
117+
signature1: Signature,
118+
/// Info necessary to declare an edge as removed.
119+
/// The bool says which party is removing the edge: false for Peer0, true for Peer1
120+
/// The signature from the party removing the edge.
121+
removal_info: Option<(bool, Signature)>,
122+
}
123+
```
124+
125+
### EdgeInfo
126+
127+
```rust
128+
struct EdgeInfo {
129+
nonce: u64,
130+
signature: Signature,
131+
}
132+
```
133+
134+
### RoutedMessage
135+
136+
```rust
137+
struct RoutedMessage {
138+
/// Peer id which is directed this message.
139+
/// If `target` is hash, this a message should be routed back.
140+
target: PeerIdOrHash,
141+
/// Original sender of this message
142+
author: PeerId,
143+
/// Signature from the author of the message. If this signature is invalid we should ban
144+
/// last sender of this message. If the message is invalid we should ben author of the message.
145+
signature: Signature,
146+
/// Time to live for this message. After passing through some hop this number should be
147+
/// decreased by 1. If this number is 0, drop this message.
148+
ttl: u8,
149+
/// Message
150+
body: RoutedMessageBody,
151+
}
152+
```
153+
154+
### RoutedMessageBody
155+
156+
```rust
157+
enum RoutedMessageBody {
158+
BlockApproval(Approval),
159+
ForwardTx(SignedTransaction),
160+
161+
TxStatusRequest(AccountId, CryptoHash),
162+
TxStatusResponse(FinalExecutionOutcomeView),
163+
QueryRequest {
164+
query_id: String,
165+
block_id_or_finality: BlockIdOrFinality,
166+
request: QueryRequest,
167+
},
168+
QueryResponse {
169+
query_id: String,
170+
response: Result<QueryResponse, String>,
171+
},
172+
ReceiptOutcomeRequest(CryptoHash),
173+
ReceiptOutComeResponse(ExecutionOutcomeWithIdAndProof),
174+
StateRequestHeader(ShardId, CryptoHash),
175+
StateRequestPart(ShardId, CryptoHash, u64),
176+
StateResponse(StateResponseInfo),
177+
PartialEncodedChunkRequest(PartialEncodedChunkRequestMsg),
178+
PartialEncodedChunkResponse(PartialEncodedChunkResponseMsg),
179+
PartialEncodedChunk(PartialEncodedChunk),
180+
Ping(Ping),
181+
Pong(Pong),
182+
}
183+
```
184+
185+
## CryptoHash
186+
187+
`CryptoHash` are objects with 256 bits of information.
188+
189+
```rust
190+
pub struct Digest(pub [u8; 32]);
191+
192+
pub struct CryptoHash(pub Digest);
193+
```

0 commit comments

Comments
 (0)