Line data Source code
1 : #ifndef HEADER_fd_src_discof_votor_fd_votor_tile_h 2 : #define HEADER_fd_src_discof_votor_fd_votor_tile_h 3 : 4 : #include "../../ballet/bls/fd_bls.h" 5 : #include "../../choreo/votor/fd_votor_hist.h" 6 : #include "../../disco/topo/fd_topo.h" 7 : #include "../../waltz/quic/tls/fd_quic_tls.h" 8 : 9 0 : #define FD_VOTOR_SIG_CERTED (0) 10 0 : #define FD_VOTOR_SIG_REPAIR (1) 11 0 : #define FD_VOTOR_SIG_LEADER (2) 12 0 : #define FD_VOTOR_SIG_REWARD (3) 13 0 : #define FD_VOTOR_SIG_QUORUM (4) 14 0 : #define FD_VOTOR_SIG_PARENT_READY (5) 15 : 16 0 : #define FD_VOTOR_NET_BURST (2UL*(1UL+FD_QUIC_TLS_HS_DATA_CNT+3UL)) /* 1 ACK + 1 TLS + 3 1-RTT pkts * 2 for both client and server. EXCLUDES DATAGRAMS. */ 17 : 18 : /* QUIC_DGRAM_BURST bounds the number of QUIC DATAGRAME frames that can 19 : fit in a single net packet. This can result in a burst of up to 9 20 : quic_server_datagram_rx calls in a single tile loop. 21 : 22 : 2048 B FD_NET_MTU 23 : - 14 B Ethernet header 24 : - 20 B IPv4 header 25 : - 8 B UDP header 26 : - 1 B short header flags 27 : - 8 B destination conn id, FD_QUIC_CONN_ID_SZ 28 : - 1 B packet number, at least 29 : - 16 B AEAD tag 30 : = 1980 B DATAGRAM frames 31 : / 207 B smallest frame: 1 B type, 2 B length, 204 B skip or final vote (a cert is at least 212 B) 32 : = 9 (9.57, and with a last frame of 205 B without its length, 8*207+205 = 1861 B still fits only 9) */ 33 : 34 0 : #define QUIC_DGRAM_BURST (9UL) 35 : 36 0 : #define FD_VOTOR_OUT_BURST (1UL+FD_VOTOR_SLOTS_PER_WINDOW+1UL+QUIC_DGRAM_BURST+1UL) /* 1 leader + 4 reward + 1 republished reward, then 2 certed or 1 quorum + 1 repair, or a catchup repair per datagram, + 1 parent ready */ 37 : 38 : /* fd_votor_certed notifies that we have a valid cert for the block 39 : reaching a given state. A final cert names only its slot, so it is 40 : reported once the notarization of that slot has formed too. 41 : 42 : kind | block_id | agg | agg2 43 : ---------------|----------|-------------|--------------------- 44 : final | ✓ | final votes | notar votes 45 : fast_final | ✓ | notar votes | - 46 : notar | ✓ | notar votes | - 47 : notar_fallback | ✓ | notar votes | notar-fallback votes 48 : skip | ✗ | skip votes | skip-fallback votes */ 49 : 50 : struct fd_votor_certed { 51 : uint kind; /* FD_CERT_KIND_* */ 52 : ulong slot; 53 : fd_hash_t block_id; 54 : fd_bls_agg_t agg; 55 : fd_bls_agg_t agg2; 56 : }; 57 : typedef struct fd_votor_certed fd_votor_certed_t; 58 : 59 : /* fd_votor_leader notifies that it is time to become leader for the 60 : window beginning from slot. */ 61 : 62 : struct fd_votor_leader { 63 : ulong slot; 64 : ulong parent_slot; 65 : fd_hash_t parent_block_id; 66 : long parent_ready_ns; 67 : }; 68 : typedef struct fd_votor_leader fd_votor_leader_t; 69 : 70 : /* fd_votor_repair names a block the pool has certs or votes for but 71 : replay has not completed, so repair fetches it. A slot past the pool 72 : window has a verified cert and a null block_id, so repair 73 : catches up toward it. */ 74 : 75 : struct fd_votor_repair { 76 : ulong slot; 77 : fd_hash_t block_id; 78 : }; 79 : typedef struct fd_votor_repair fd_votor_repair_t; 80 : 81 : /* fd_votor_reward notifies Votor has produced a new reward cert (agg of 82 : all skip / reward votes). Votor publishes a fd_votor_reward_t for 83 : every slot of a leader window right after the window's 84 : fd_votor_leader_t (replay only reads them at block end, for the 85 : footer), and may publish add'l reward certs that include more votes 86 : later. */ 87 : 88 : struct fd_votor_reward { 89 : ulong slot; 90 : fd_hash_t block_id; 91 : fd_bls_agg_t agg_notar; 92 : fd_bls_agg_t agg_skip; 93 : }; 94 : typedef struct fd_votor_reward fd_votor_reward_t; 95 : 96 : /* fd_votor_quorum notifies that the pool's votes or certs moved a block 97 : to a new state outside of constructing a cert: it became SafeToNotar 98 : (Definition 16), or a descendant finalization implicitly finalized or 99 : skipped. block_id is all 0s for a skipped slot. */ 100 : 101 0 : #define FD_VOTOR_QUORUM_KIND_SAFE_TO_NOTAR (0) 102 0 : #define FD_VOTOR_QUORUM_KIND_IMPLICITLY_SKIPPED (1) 103 0 : #define FD_VOTOR_QUORUM_KIND_IMPLICITLY_FINALIZED (2) 104 : 105 : struct fd_votor_quorum { 106 : uint kind; /* FD_VOTOR_QUORUM_KIND_* */ 107 : ulong slot; 108 : fd_hash_t block_id; 109 : }; 110 : typedef struct fd_votor_quorum fd_votor_quorum_t; 111 : 112 : /* fd_votor_parent_ready notifies that slot, a window start, is the 113 : highest certs have made ParentReady, so earlier windows are skipped. */ 114 : 115 : struct fd_votor_parent_ready { 116 : ulong slot; 117 : }; 118 : typedef struct fd_votor_parent_ready fd_votor_parent_ready_t; 119 : 120 : union fd_votor_msg { 121 : fd_votor_certed_t certed; 122 : fd_votor_repair_t repair; 123 : fd_votor_leader_t leader; 124 : fd_votor_reward_t reward; 125 : fd_votor_quorum_t quorum; 126 : fd_votor_parent_ready_t parent_ready; 127 : }; 128 : typedef union fd_votor_msg fd_votor_msg_t; 129 : 130 : /* fd_votor_hist_msg is one frame on the votor_hist link to the failover 131 : tile, with our replay slots and our own vote history. */ 132 : 133 0 : #define FD_VOTOR_HIST_SIG (0UL) 134 : 135 : struct fd_votor_hist_msg { 136 : fd_pubkey_t identity; /* identity installed when this history was published */ 137 : ulong replay_slot; /* highest slot replay completed, ULONG_MAX before any */ 138 : ulong root_slot; /* replay's root at the last completed slot, ULONG_MAX before any */ 139 : ulong vote_slot; /* the history's tip, ULONG_MAX while it is empty */ 140 : int has_vote; /* we sent a vote just before this frame, so vote_slot is a vote we signed */ 141 : int truncated; /* the export dropped old windows and lifted the anchor */ 142 : int ranked; /* the installed identity votes and is ranked in an epoch we hold */ 143 : fd_votor_hist_t hist; 144 : }; 145 : typedef struct fd_votor_hist_msg fd_votor_hist_msg_t; 146 : 147 : /* Adoption of a peer's vote history. */ 148 : 149 : /* Frame sizes */ 150 : 151 0 : #define FD_VOTOR_ADOPT_REQ_HDR_SZ (32UL) /* the identity the adoption is for, before the payload */ 152 0 : #define FD_VOTOR_ADOPT_EMPTY_SZ (8UL) /* an empty payload, a slot as a ulong */ 153 : 154 : /* Result codes */ 155 : 156 0 : #define FD_VOTOR_ADOPT_SUCCESS (0UL) 157 0 : #define FD_VOTOR_ADOPT_ERR_DECODE (1UL) 158 0 : #define FD_VOTOR_ADOPT_ERR_INVALID (2UL) 159 0 : #define FD_VOTOR_ADOPT_ERR_UNREPLAYED_ROOT (3UL) /* the history's finality anchor is past our replayed slots */ 160 0 : #define FD_VOTOR_ADOPT_ERR_UNREPLAYED (4UL) /* consensus is not up yet, ask again as replay moves */ 161 0 : #define FD_VOTOR_ADOPT_ERR_STALE (5UL) /* older than the votes this identity sent from here */ 162 0 : #define FD_VOTOR_ADOPT_ERR_CAPACITY (6UL) /* retained local and imported slots exceed capacity */ 163 0 : #define FD_VOTOR_ADOPT_RESULT_CNT (7UL) 164 : 165 : struct fd_votor_adopt_result { 166 : ulong result; 167 : ulong root; /* our finality anchor after the adoption */ 168 : ulong vote_slot; /* the adopted history's tip, ULONG_MAX for an empty one */ 169 : ulong vote_bound; /* we cast no vote at or below this slot, ULONG_MAX when there is none */ 170 : }; 171 : typedef struct fd_votor_adopt_result fd_votor_adopt_result_t; 172 : 173 : extern fd_topo_run_tile_t fd_tile_votor; 174 : 175 : #endif /* HEADER_fd_src_discof_votor_fd_votor_tile_h */