Line data Source code
1 : #ifndef HEADER_fd_src_choreo_votor_fd_vote_history_serde_h 2 : #define HEADER_fd_src_choreo_votor_fd_vote_history_serde_h 3 : 4 : /* Reads and writes Agave's Alpenglow vote history file, 5 : vote_history-<pubkey>.bin, wincode (bincode layout) of 6 : SavedVoteHistoryVersions::Current which has the identity's Ed25519 7 : signature with VoteHistory body. */ 8 : 9 : #include "fd_votor_base.h" 10 : 11 0 : #define FD_VOTE_HISTORY_SERDE_KIND (0U) /* SavedVoteHistoryVersions::Current */ 12 0 : #define FD_VOTE_HISTORY_SERDE_SIG_OFF (4UL) 13 0 : #define FD_VOTE_HISTORY_SERDE_DATA_OFF (4UL+64UL+8UL) /* kind, signature, data_sz */ 14 : 15 0 : #define FD_VOTE_HISTORY_SER_SZ (FD_VOTE_HISTORY_SERDE_DATA_OFF+32UL+9UL*8UL+8UL) /* the file we write: identity, 9 empty collections, root */ 16 : #define FD_VOTE_HISTORY_DE_MAX (FD_VOTE_HISTORY_SERDE_DATA_OFF+(18UL<<30)) /* the largest file Agave restores, but for trailing bytes: VOTE_HISTORY_PREALLOCATION_SIZE_LIMIT on the history it signs */ 17 : 18 : /* VotePayloadToSign wire tags. */ 19 0 : #define FD_VOTE_HISTORY_SERDE_TAG_NOTAR (1U) 20 0 : #define FD_VOTE_HISTORY_SERDE_TAG_FINAL (2U) 21 0 : #define FD_VOTE_HISTORY_SERDE_TAG_SKIP (3U) 22 0 : #define FD_VOTE_HISTORY_SERDE_TAG_NOTAR_FALLBACK (4U) 23 0 : #define FD_VOTE_HISTORY_SERDE_TAG_SKIP_FALLBACK (5U) 24 0 : #define FD_VOTE_HISTORY_SERDE_TAG_GENESIS (6U) 25 : 26 : /* Return codes of fd_vote_history_de. */ 27 0 : #define FD_VOTE_HISTORY_DE_SUCCESS ( 0) 28 0 : #define FD_VOTE_HISTORY_DE_ERR_SIZE (-1) /* truncated, or too large */ 29 0 : #define FD_VOTE_HISTORY_DE_ERR_VERSION (-2) /* not SavedVoteHistoryVersions::Current */ 30 0 : #define FD_VOTE_HISTORY_DE_ERR_SIG (-3) /* the signature does not verify under identity */ 31 0 : #define FD_VOTE_HISTORY_DE_ERR_IDENTITY (-4) /* the node pubkey in the file is not identity (Agave's WrongVoteHistory) */ 32 0 : #define FD_VOTE_HISTORY_DE_ERR_HISTORY (-5) /* a bad vote tag */ 33 : 34 : FD_PROTOTYPES_BEGIN 35 : 36 : /* fd_vote_history_ser serializes an Agave-compatible vote history 37 : file, with the end of the window of our highest notar or skip slot as 38 : the root. There are two edge cases, both of which only matter when 39 : either Agave or Firedancer is in a bad state: 40 : 41 : 1. Equivocation (safety): if the Agave failover node's blockstore 42 : root is not on the same fork as our highest notar or skip slot, it 43 : fails to boot. 44 : 2. Standstill (liveness): Agave's set-identity ends a standstill 45 : detected below the root, delaying its re-broadcast. 46 : 47 : The FD->Agave failover is best effort, as Agave has inherently 48 : different data structures than Firedancer. Operators should not 49 : expect a 1-to-1 correspondence between Firedancer's state and Agave's 50 : state. The vote history file is simply to protect against 51 : double-voting (equivocation). */ 52 : 53 : void 54 : fd_vote_history_ser( uchar const identity[ static 32 ], 55 : ulong root, 56 : uchar buf[ static FD_VOTE_HISTORY_SER_SZ ] ); 57 : 58 : /* fd_vote_history_de deserializes an Agave-compatible vote history 59 : file. The vote history file determines the minimum slot we can vote 60 : for (wait_to_vote_slot). The vote history file must be well-formed 61 : and signed by the provided identity key. Returns 62 : FD_VOTE_HISTORY_DE_SUCCESS or an FD_VOTE_HISTORY_DE_ERR_* code. 63 : 64 : The Agave->FD failover is best effort, as Agave has inherently 65 : different data structures than Firedancer. Operators should not 66 : expect a 1-to-1 correspondence between Agave's state and Firedancer's 67 : state. The vote history file is simply to protect against 68 : double-voting (equivocation). */ 69 : 70 : int 71 : fd_vote_history_de( uchar const * buf, 72 : ulong buf_sz, 73 : uchar const identity[ static 32 ], 74 : ulong * wait_to_vote_slot ); 75 : 76 : FD_PROTOTYPES_END 77 : 78 : #endif /* HEADER_fd_src_choreo_votor_fd_vote_history_serde_h */