Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_gossip_crds_fd_crds_h
2 : #define HEADER_fd_src_flamenco_gossip_crds_fd_crds_h
3 :
4 : #include "fd_gossip_wsample.h"
5 : #include "fd_gossip_message.h"
6 : #include "fd_gossip_out.h"
7 : #include "fd_gossip_purged.h"
8 :
9 : #include "../../util/net/fd_net_headers.h"
10 : #include "../../disco/metrics/generated/fd_metrics_enums.h"
11 :
12 : struct fd_crds_entry_private;
13 : typedef struct fd_crds_entry_private fd_crds_entry_t;
14 :
15 : struct fd_crds_private;
16 : typedef struct fd_crds_private fd_crds_t;
17 :
18 0 : #define FD_CRDS_ALIGN 128UL
19 :
20 0 : #define FD_CRDS_MAGIC (0xf17eda2c37c7d50UL) /* firedancer crds version 0*/
21 :
22 : struct fd_crds_metrics {
23 : ulong count[ FD_METRICS_ENUM_CRDS_VALUE_TYPE_CNT ];
24 : ulong expired_cnt;
25 : ulong evicted_cnt;
26 : ulong relay_coalesced_cnt;
27 :
28 : ulong peer_staked_cnt;
29 : ulong peer_unstaked_cnt;
30 : ulong peer_visible_stake;
31 : ulong peer_evicted_cnt;
32 : };
33 :
34 : typedef struct fd_crds_metrics fd_crds_metrics_t;
35 :
36 0 : #define FD_GOSSIP_ACTIVITY_CHANGE_TYPE_ACTIVE (1)
37 0 : #define FD_GOSSIP_ACTIVITY_CHANGE_TYPE_INACTIVE (2)
38 :
39 : typedef void (*fd_gossip_activity_update_fn)( void * ctx,
40 : fd_pubkey_t const * identity,
41 : fd_gossip_contact_info_t const * ci,
42 : int change_type );
43 :
44 : FD_PROTOTYPES_BEGIN
45 :
46 : FD_FN_CONST ulong
47 : fd_crds_align( void );
48 :
49 : FD_FN_CONST ulong
50 : fd_crds_footprint( ulong ele_max );
51 :
52 : typedef struct fd_active_set_private fd_active_set_t;
53 :
54 : void *
55 : fd_crds_new( void * shmem,
56 : fd_ip4_port_t const * entrypoints,
57 : ulong entrypoints_cnt,
58 : fd_gossip_wsample_t * wsample,
59 : fd_active_set_t * active_set, /* TODO: Remove .. circular dep */
60 : fd_rng_t * rng,
61 : ulong ele_max,
62 : fd_gossip_purged_t * purged,
63 : fd_gossip_activity_update_fn activity_update_fn,
64 : void * activity_update_fn_ctx,
65 : fd_gossip_out_ctx_t * gossip_update_out );
66 :
67 : fd_crds_t *
68 : fd_crds_join( void * shcrds );
69 :
70 : fd_crds_metrics_t const *
71 : fd_crds_metrics( fd_crds_t const * crds );
72 :
73 : /* fd_crds_advance performs housekeeping operations and should be run
74 : as a part of a gossip advance loop. The following operations are
75 : performed:
76 : - expire: removes stale entries from the replicated data store.
77 : CRDS values from staked nodes expire roughly an epoch after they
78 : are created, and values from non-staked nodes expire after 15
79 : seconds. Removed contact info entries are also published as gossip
80 : updates via stem.
81 : - re-weigh: peers are downsampled in the peer sampler if they have
82 : not been refreshed in <60s.
83 :
84 : There is one exception, when the node is first bootstrapping, and
85 : has not yet seen any staked nodes, values do not expire at all. */
86 :
87 : void
88 : fd_crds_advance( fd_crds_t * crds,
89 : long now,
90 : fd_stem_context_t * stem,
91 : int * charge_busy );
92 :
93 : /* fd_crds_len returns the number of entries in the CRDS table. This
94 : does not include purged entries, which have a separate queue tracking
95 : them. See fd_crds_purged_* APIs below. */
96 :
97 : ulong
98 : fd_crds_len( fd_crds_t const * crds );
99 :
100 : /* fd_crds_insert upserts a CRDS value into the data store. If the
101 : value's key is not yet present, a new entry is acquired and indexed.
102 : If a matching key already exists, the candidate is compared against
103 : the incumbent using wallclock (and outset for ContactInfo); the
104 : winner is kept and the loser is purged.
105 :
106 : On top of inserting the CRDS entry, this function also updates the
107 : sidetable of ContactInfo entries and the peer samplers if the entry
108 : is a ContactInfo. is_from_me indicates the CRDS entry originates
109 : from this node. We exclude our own entries from peer samplers.
110 : origin_stake is used to weigh the peer in the samplers. is_push is
111 : set if the value arrived in a push message.
112 :
113 : stem is used to publish updates to {ContactInfo, Vote, DuplicateShred,
114 : SnapshotHashes} entries.
115 :
116 : Returns 0L on successful upsert, -1L if the candidate was stale
117 : (not inserted), or >0 if the candidate was a duplicate. For a push
118 : duplicate the return is 1 plus the number of earlier pushes of the
119 : value, counting the push that inserted it; a pull duplicate returns
120 : 1 and does not count.
121 :
122 : If opt_relay is non-NULL, *opt_relay is set to 1 if the upserted
123 : value should be pushed to peers now, else 0. Versions of one key
124 : arriving within 100 ms of its last relay are held, and
125 : fd_crds_advance pushes the latest of them once that passes, so peers
126 : see at most one version of a key per 100 ms. Values outside the
127 : +/-15 s wallclock window are never relayed. */
128 :
129 : long
130 : fd_crds_insert( fd_crds_t * crds,
131 : fd_gossip_value_t const * value,
132 : uchar const * value_bytes,
133 : ulong value_bytes_len,
134 : ulong origin_stake,
135 : int origin_ping_tracked,
136 : int is_me,
137 : int is_push,
138 : long now,
139 : fd_stem_context_t * stem,
140 : int * opt_relay );
141 :
142 : void
143 : fd_crds_entry_value( fd_crds_entry_t const * entry,
144 : uchar const ** value_bytes,
145 : ulong * value_sz );
146 :
147 : /* fd_crds_entry_wallclock returns the originator's wallclock timestamp
148 : for this entry, in milliseconds. This is the wallclock the
149 : originator attached when they created the CRDS value. */
150 :
151 : ulong
152 : fd_crds_entry_wallclock( fd_crds_entry_t const * entry );
153 :
154 : /* fd_crds_entry_hash returns a pointer to the 32b sha256 hash of the
155 : entry's value hash. This is used for constructing a bloom filter. */
156 :
157 : uchar const *
158 : fd_crds_entry_hash( fd_crds_entry_t const * entry );
159 :
160 : /* fd_crds_hset returns the dense index of the value hashes of all
161 : entries in the table, see fd_gossip_hset.h. */
162 :
163 : fd_gossip_hset_t const *
164 : fd_crds_hset( fd_crds_t const * crds );
165 :
166 : /* fd_crds_peer_count returns the number of Contact Info entries
167 : present in the sidetable. The lifetime of a Contact Info entry
168 : tracks the lifetime of the corresponding CRDS entry. */
169 :
170 : ulong
171 : fd_crds_peer_count( fd_crds_t const * crds );
172 :
173 : ulong
174 : fd_crds_entrypoint_fresh_cnt( fd_crds_t const * crds );
175 :
176 : fd_gossip_contact_info_t const *
177 : fd_crds_ci( fd_crds_t const * crds,
178 : ulong ci_idx );
179 :
180 : uchar const *
181 : fd_crds_ci_pubkey( fd_crds_t const * crds,
182 : ulong ci_idx );
183 :
184 : ulong
185 : fd_crds_ci_idx( fd_crds_t const * crds,
186 : uchar const * pubkey );
187 :
188 : /* fd_crds_entry_at returns the entry at pool index idx, as reported
189 : by the hset (fd_gossip_hset_iter_owner). idx must be in the table
190 : (the hset only reports live entries). */
191 :
192 : fd_crds_entry_t const *
193 : fd_crds_entry_at( fd_crds_t const * crds,
194 : ulong idx );
195 :
196 : FD_PROTOTYPES_END
197 :
198 : #endif /* HEADER_fd_src_flamenco_gossip_crds_fd_crds_h */
|