Skip to content

Commit 16a3a8a

Browse files
committed
gossip2: public type definitions
1 parent fdbf941 commit 16a3a8a

File tree

3 files changed

+214
-0
lines changed

3 files changed

+214
-0
lines changed

src/choreo/eqvoc/fd_eqvoc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include "../../ballet/shred/fd_shred.h"
55
#include "../../flamenco/leaders/fd_leaders.h"
6+
#include "../../flamenco/gossip/fd_gossip_types.h"
67
#include "../fd_choreo_base.h"
78

89
/* fd_eqvoc presents an API for detecting and sending / receiving proofs
@@ -90,6 +91,8 @@ typedef struct fd_eqvoc_fec fd_eqvoc_fec_t;
9091
#define FD_EQVOC_PROOF_CHUNK_CNT (( FD_EQVOC_PROOF_SZ / FD_EQVOC_PROOF_CHUNK_SZ ) + 1) /* 3 */
9192
#define FD_EQVOC_PROOF_SZ (2*FD_SHRED_MAX_SZ + 2*sizeof(ulong)) /* 2 shreds prefixed with sz, encoded in 3 chunks */
9293

94+
FD_STATIC_ASSERT( FD_EQVOC_PROOF_CHUNK_SZ==FD_GOSSIP_DUPLICATE_SHRED_MAX_CHUNKS, "Update duplicate shred max chunks size" );
95+
9396
/* The chunk_cnt is encoded in a UCHAR_MAX, so you can have at most
9497
UCHAR_MAX chunks */
9598

src/flamenco/gossip/Local.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
ifdef FD_HAS_HOSTED
22
ifdef FD_HAS_INT128
33
$(call add-hdrs,fd_gossip.h fd_contact_info.h)
4+
$(call add-hdrs,fd_gossip_types.h)
45
$(call add-objs,fd_gossip fd_contact_info,fd_flamenco)
56
$(call make-bin,fd_gossip_spy,fd_gossip_spy,fd_flamenco fd_ballet fd_util)
67

src/flamenco/gossip/fd_gossip_types.h

Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
#ifndef HEADER_fd_src_flamenco_gossip_fd_gossip_types_h
2+
#define HEADER_fd_src_flamenco_gossip_fd_gossip_types_h
3+
4+
/* The gossip tile produces an output stream of update messages as it
5+
runs, which are published to a link for other tiles to consume.
6+
7+
The formt and protocol of the update messages is defined here.
8+
9+
Messages are published one by one incrementally, as they are
10+
received, although expirations or removals will not be published
11+
except for contact information which publishes a removal stream so
12+
that consumers of the updates can mirror the true gossip table.
13+
14+
Not all gossip messages are published, and some are consumed just by
15+
the gossip tile itself. */
16+
17+
#include "../types/fd_types_custom.h"
18+
#include "../../util/net/fd_net_headers.h"
19+
20+
/* The tag is the kind of gossip message that is being sent. It will be
21+
put both in the fragment signature, and in the message itself. */
22+
23+
#define FD_GOSSIP_UPDATE_TAG_CONTACT_INFO (0)
24+
#define FD_GOSSIP_UPDATE_TAG_CONTACT_INFO_REMOVE (1)
25+
#define FD_GOSSIP_UPDATE_TAG_LOWEST_SLOT (2)
26+
#define FD_GOSSIP_UPDATE_TAG_VOTE (3)
27+
#define FD_GOSSIP_UPDATE_TAG_DUPLICATE_SHRED (4)
28+
#define FD_GOSSIP_UPDATE_TAG_SNAPSHOT_HASHES (5)
29+
30+
/* The maximum number of contact infos that may be present at any one
31+
time. If new contact infos are added, a removal will be issued first
32+
to make space. This is a hard limit, and the consumer of the contact
33+
info messages can assume it is always respected.
34+
35+
The contact info messages are designed to be consumed in an
36+
incremental way. In particular, CONTACT_INFO and CONTACT_INFO_REMOVE
37+
messages are both sent with an idx field, which is the index of the
38+
contact info in an imaginary array of contact infos. Updates will
39+
always have the same idx for the same pubkey, and removes will
40+
likewise have the same idx for the pubkey being removed. A consumer
41+
of contact info updates can therefore simply maintain a local array
42+
of contact infos, and update it with the idx field. */
43+
44+
#define FD_CONTACT_INFO_TABLE_SIZE (32768UL)
45+
46+
#define FD_CONTACT_INFO_SOCKET_GOSSIP ( 0)
47+
#define FD_CONTACT_INFO_SOCKET_SERVE_REPAIR_QUIC ( 1)
48+
#define FD_CONTACT_INFO_SOCKET_RPC ( 2)
49+
#define FD_CONTACT_INFO_SOCKET_RPC_PUBSUB ( 3)
50+
#define FD_CONTACT_INFO_SOCKET_SERVE_REPAIR ( 4)
51+
#define FD_CONTACT_INFO_SOCKET_TPU ( 5)
52+
#define FD_CONTACT_INFO_SOCKET_TPU_FORWARDS ( 6)
53+
#define FD_CONTACT_INFO_SOCKET_TPU_FORWARDS_QUIC ( 7)
54+
#define FD_CONTACT_INFO_SOCKET_TPU_QUIC ( 8)
55+
#define FD_CONTACT_INFO_SOCKET_TPU_VOTE ( 9)
56+
#define FD_CONTACT_INFO_SOCKET_TVU (10)
57+
#define FD_CONTACT_INFO_SOCKET_TVU_QUIC (11)
58+
#define FD_CONTACT_INFO_SOCKET_TPU_VOTE_QUIC (12)
59+
#define FD_CONTACT_INFO_SOCKET_LAST (12)
60+
61+
/* https://github.com/anza-xyz/agave/blob/540d5bc56cd44e3cc61b179bd52e9a782a2c99e4/version/src/lib.rs#L95-L105 */
62+
63+
#define FD_CONTACT_INFO_VERSION_CLIENT_SOLANA_LABS (0)
64+
#define FD_CONTACT_INFO_VERSION_CLIENT_JITO_LABS (1)
65+
#define FD_CONTACT_INFO_VERSION_CLIENT_FIREDANCER (2)
66+
#define FD_CONTACT_INFO_VERSION_CLIENT_AGAVE (3)
67+
68+
/* A contact info represents a peer node in the cluster that is
69+
publishing information about itself to the gossip network. It it
70+
sent when the tag is FD_GOSSIP_UPDATE_TAG_CONTACT_INFO.
71+
72+
Contact infos are already deduplicated, so the same pubkey will not
73+
appear twice, and the number of contact infos outstanding is limited
74+
to FD_CONTACT_INFO_TABLE_SIZE. If more contact infos are received,
75+
the oldest ones are first removed with a
76+
FD_GOSSIP_UPDATE_TAG_CONTACT_INFO_REMOVE fragment.
77+
78+
Contact infos are regularly updated, for example if a node changes
79+
its IP address or port. More typically nodes just periodically
80+
republish their contact info with an updated wallclock. When an
81+
existing contact info is updated, a FD_GOSSIP_UPDATE_TAG_CONTACT_INFO
82+
fragment is sent with the same pubkey.
83+
84+
Contact information is not well-validated by the gossip network, and
85+
for example the wallclock may be old, or in the future, and the
86+
sockets may be unroutable or invalid (a private network), and the
87+
version fields are completely arbitrary.
88+
89+
However, the pubkey is authenticated, as messages are signed.
90+
91+
TODO: Remove the _upd suffixes once the types are removed from
92+
fd_types.h and fd_contact_info.h */
93+
94+
struct fd_contact_info_upd {
95+
fd_pubkey_t pubkey; /* The identity public key of the peer node */
96+
ushort shred_version; /* The shred version of the peer node, should be non-zero but not required */
97+
98+
long instance_creation_wallclock_nanos;
99+
long wallclock_nanos; /* The timestamp on the producer side of when the contact info was signed */
100+
101+
/* Peer nodes declare a list of ip:port pairs corresponding to
102+
standard Solana protocols that they support. A value of 0:0
103+
indicates the node does not advertise that protocol. For example,
104+
sockets[ FD_CONTACT_INFO_SOCKET_RPC ] is the IP address and port
105+
for the RPC service of the node. */
106+
fd_ip4_port_t sockets[ FD_CONTACT_INFO_SOCKET_LAST+1UL ];
107+
108+
struct {
109+
uchar client; /* Any uchar in [0, 255], although typically one of FD_CONTACT_INFO_VERSION_CLIENT_* indicating the self-reported client version */
110+
111+
ushort major; /* The self-reported major version of the client */
112+
ushort minor; /* The self-reported minor version of the client */
113+
ushort patch; /* The self-reported patch version of the client */
114+
115+
uint commit; /* The self-reported commit hash of the client, in little-endian order, or 0 if no commit hash was provided */
116+
uint feature_set; /* The self-reported feature set of the client, in little-endian order */
117+
} version;
118+
};
119+
120+
typedef struct fd_contact_info_upd fd_contact_info_upd_t;
121+
122+
/* A gossip vote represents a vote transaction that was sent to us by a
123+
peer node. It is sent when the tag is FD_GOSSIP_UPDATE_TAG_VOTE.
124+
Votes are typically sent over the TPU, but also via. gossip for
125+
redundancy.
126+
127+
The transaction is not validated or parsed in any way yet, and in
128+
particular the signatures have not been verified. Transaction data
129+
is arbitrary and could be empty or corrupt or malicious. */
130+
131+
struct fd_gossip_vote_upd {
132+
uchar vote_tower_index;
133+
ulong txn_sz;
134+
uchar txn[ 1232UL ];
135+
};
136+
137+
typedef struct fd_gossip_vote_upd fd_gossip_vote_upd_t;
138+
139+
#define FD_GOSSIP_DUPLICATE_SHRED_MAX_CHUNKS (1054UL)
140+
141+
/* An edge case in the network is "equivocation" when a node publishes
142+
conflicting shred data for its leader slot. In future this may be
143+
a slashable offense, but for now it simply "proven" on the chain and
144+
communicated among peers. */
145+
146+
struct fd_gossip_duplicate_shred_upd {
147+
ushort index;
148+
ulong slot;
149+
uchar num_chunks;
150+
uchar chunk_index;
151+
ulong chunk_len;
152+
uchar chunk[ FD_GOSSIP_DUPLICATE_SHRED_MAX_CHUNKS ];
153+
};
154+
155+
typedef struct fd_gossip_duplicate_shred_upd fd_gossip_duplicate_shred_upd_t;
156+
157+
struct fd_gossip_snapshot_hash_pair {
158+
ulong slot;
159+
uchar hash[ 32UL ];
160+
};
161+
162+
typedef struct fd_gossip_snapshot_hash_pair fd_gossip_snapshot_hash_pair_t;
163+
164+
#define FD_GOSSIP_SNAPSHOT_HASHES_MAX_INCREMENTAL (25UL)
165+
166+
/* Each peer node which is serving snapshots will periodically
167+
publish a snapshot hash update, which contains the hashes of the
168+
latest snapshots it has available. This is sent when the tag is
169+
FD_GOSSIP_UPDATE_TAG_SNAPSHOT_HASHES.
170+
171+
The full field indicates the full snapshot slot and hash, and then a
172+
list of recent incremental snapshots is provided which build on top
173+
of the full snapshot. */
174+
175+
struct fd_gossip_snapshot_hashes_upd {
176+
fd_gossip_snapshot_hash_pair_t full[ 1 ];
177+
178+
ulong incremental_len;
179+
fd_gossip_snapshot_hash_pair_t incremental[ FD_GOSSIP_SNAPSHOT_HASHES_MAX_INCREMENTAL ];
180+
};
181+
182+
typedef struct fd_gossip_snapshot_hashes_upd fd_gossip_snapshot_hashes_upd_t;
183+
184+
struct fd_gossip_update_message {
185+
uchar tag;
186+
187+
uchar origin_pubkey[ 32UL ];
188+
ulong origin_stake;
189+
long wallclock_nanos;
190+
191+
union {
192+
struct {
193+
ulong idx; /* Index into flat array to place this contact info, see comments on FD_CONTACT_INFO_TABLE_SIZE */
194+
fd_contact_info_upd_t contact_info[ 1 ];
195+
} contact_info;
196+
197+
struct {
198+
ulong idx; /* Index into flat array of contact info to remove, see FD_CONTACT_INFO_TABLE_SIZE */
199+
} contact_info_remove;
200+
201+
ulong lowest_slot;
202+
fd_gossip_vote_upd_t vote;
203+
fd_gossip_duplicate_shred_upd_t duplicate_shred;
204+
fd_gossip_snapshot_hashes_upd_t snapshot_hashes;
205+
};
206+
};
207+
208+
typedef struct fd_gossip_update_message fd_gossip_update_message_t;
209+
210+
#endif /* HEADER_fd_src_flamenco_gossip_fd_gossip_types_h */

0 commit comments

Comments
 (0)