LCOV - code coverage report
Current view: top level - choreo/tower - fd_tower_serdes.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 6 0.0 %
Date: 2026-10-22 18:10:43 Functions: 0 22 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_choreo_tower_fd_tower_serdes_h
       2             : #define HEADER_fd_src_choreo_tower_fd_tower_serdes_h
       3             : 
       4             : /* fd_tower_serdes.h provides APIs for serializing and deserializing
       5             :    vote accounts and instructions. */
       6             : 
       7             : #include "../fd_choreo_base.h"
       8             : #include "../../ballet/txn/fd_txn.h"
       9             : #include "../../flamenco/runtime/program/vote/fd_vote_codec.h"
      10             : 
      11             : struct fd_tower_vote;
      12             : typedef struct fd_tower_vote fd_tower_vote_t;
      13             : 
      14             : /* FD_VOTE_IX_KIND_* give vote program instruction discriminants (first
      15             :    four bytes of instruction data).  Older instruction types are ignored
      16             :    by tower. */
      17             : 
      18             : #define FD_VOTE_IX_KIND_TOWER_SYNC        (14)
      19             : #define FD_VOTE_IX_KIND_TOWER_SYNC_SWITCH (15)
      20             : 
      21             : /* fd_compact_tower_sync_serde describes the serialization /
      22             :    deserialization schema of a CompactTowerSync vote instruction.  There
      23             :    are various legacy instructions for vote transactions, but current
      24             :    mainnet votes are almost exclusively this instruction. */
      25             : 
      26             : struct fd_compact_tower_sync_serde { /* CompactTowerSync */
      27             :   ulong root;                        /* u64              */
      28             :   struct {
      29             :     ushort lockouts_cnt;             /* ShortU16         */
      30             :     struct {
      31             :       ulong offset;                  /* VarInt           */
      32             :       uchar confirmation_count;      /* u8               */
      33             :     } lockouts[31];
      34             :   };
      35             :   fd_hash_t hash;                    /* [u8; 32]         */
      36             :   struct {
      37             :     uchar timestamp_option;          /* Option           */
      38             :     long  timestamp;                 /* UnixTimestamp    */
      39             :   };
      40             :   fd_hash_t block_id;                /* [u8; 32]         */
      41             : };
      42             : typedef struct fd_compact_tower_sync_serde fd_compact_tower_sync_serde_t;
      43             : 
      44             : /* fd_compact_tower_sync_ser serializes fd_compact_tower_sync_serde_t
      45             :    into a buffer.  Returns 0 on success, -1 if the lockouts_cnt is
      46             :    greater than FD_TOWER_VOTE_MAX or buf_max is too small to fit the
      47             :    serialized data.  On success, sets *buf_sz to the number of bytes
      48             :    written if buf_sz is non-NULL. */
      49             : 
      50             : int
      51             : fd_compact_tower_sync_ser( fd_compact_tower_sync_serde_t const * serde,
      52             :                            uchar *                               buf,
      53             :                            ulong                                 buf_max,
      54             :                            ulong *                               buf_sz );
      55             : 
      56             : /* fd_compact_tower_sync_de deserializes at most buf_sz of buf into
      57             :    fd_compact_tower_sync_serde_t.  Designed to deserialize untrusted
      58             :    inputs (gossip / TPU vote txns).  Assumes buf is at least of size
      59             :    buf_sz.  Returns 0 on success, -1 on deserialization failure.  Note:
      60             :    the return value only indicates whether the wire format was valid,
      61             :    not whether the resulting tower is semantically valid (e.g. slots
      62             :    and confirmations are monotonically increasing).  Callers must
      63             :    validate the deserialized tower contents separately. */
      64             : 
      65             : int
      66             : fd_compact_tower_sync_de( fd_compact_tower_sync_serde_t * serde,
      67             :                           uchar const *                   buf,
      68             :                           ulong                           buf_sz );
      69             : 
      70             : /* fd_compact_tower_sync_to_votes expands the lockout offsets into
      71             :    ascending votes (out holds FD_TOWER_VOTE_MAX), count and root,
      72             :    ULONG_MAX if none.  Returns -1 for a repeated or descending slot, a
      73             :    bad confirmation count or a vote past the lockout of the vote below. */
      74             : 
      75             : int
      76             : fd_compact_tower_sync_to_votes( fd_compact_tower_sync_serde_t const * serde,
      77             :                                 fd_tower_vote_t *                     out,
      78             :                                 ulong *                               out_cnt,
      79             :                                 ulong *                               out_root );
      80             : 
      81             : /* A buffer with capacity FD_VOTE_STATE_DATA_MAX can fit any valid vote
      82             :    account supported by tower (v2, v3, and v4). */
      83             : 
      84             : #define FD_VOTE_STATE_DATA_MAX (3762UL)
      85             : 
      86             : /* FD_VOTE_ACC_V* give vote account/state versions. */
      87             : 
      88           0 : #define FD_VOTE_ACC_V2 (1)
      89           0 : #define FD_VOTE_ACC_V3 (2)
      90           0 : #define FD_VOTE_ACC_V4 (3)
      91             : FD_STATIC_ASSERT( FD_VOTE_ACC_V2==fd_vote_state_versioned_enum_v1_14_11, FD_VOTE_ACC_V2 );
      92             : FD_STATIC_ASSERT( FD_VOTE_ACC_V3==fd_vote_state_versioned_enum_v3,       FD_VOTE_ACC_V3 );
      93             : FD_STATIC_ASSERT( FD_VOTE_ACC_V4==fd_vote_state_versioned_enum_v4,       FD_VOTE_ACC_V4 );
      94             : 
      95             : /* fd_vote_acc describes the layout of a vote state stored in a vote
      96             :    account.  The vote_acc_{...} deserializers assume trusted input
      97             :    (account data written to by the vote program).  These structs are
      98             :    used to support zero-copy access (direct casts) of byte arrays
      99             :    containing the vote account data.
     100             : 
     101             :    fd_vote_acc is versioned, and the serialized formats differ depending
     102             :    on this.  They correspond to Agave's VoteState0_23_5,
     103             :    VoteState1_14_11 and VoteState structs.
     104             : 
     105             :    VoteStatev0_23_5 is deprecated and there are no longer vote accounts
     106             :    of that version on testnet / mainnet.  VoteState1_14_11 corresponds
     107             :    to FD_VOTE_ACC_V2 and VoteState corresponds to FD_VOTE_ACC_V3.  The
     108             :    only difference between the two is the votes in V3 contain an
     109             :    additional uchar field `latency`.
     110             : 
     111             :    The binary layout begins with metadata in the vote account, followed
     112             :    by the voter's votes (tower), and terminates with the root. */
     113             : 
     114             : struct __attribute__((packed)) fd_vote_acc_vote {
     115             :   uchar latency;
     116             :   ulong slot;
     117             :   uint  conf;
     118             : };
     119             : typedef struct fd_vote_acc_vote fd_vote_acc_vote_t;
     120             : 
     121             : struct __attribute__((packed)) fd_vote_acc_vote_v2 {
     122             :   ulong slot;
     123             :   uint  conf;
     124             : };
     125             : typedef struct fd_vote_acc_vote_v2 fd_vote_acc_vote_v2_t;
     126             : 
     127             : struct __attribute__((packed)) fd_vote_acc {
     128             :   uint kind;
     129             :   union __attribute__((packed)) {
     130             :     struct __attribute__((packed)) {
     131             :       fd_pubkey_t node_pubkey;
     132             :       fd_pubkey_t authorized_withdrawer;
     133             :       uchar       commission;
     134             :       ulong       votes_cnt;
     135             :       fd_vote_acc_vote_v2_t votes[31]; /* variable-length */
     136             :       /* uchar root_option */
     137             :       /* ulong root */
     138             :     } v2;
     139             : 
     140             :     struct __attribute__((packed)) {
     141             :       fd_pubkey_t        node_pubkey;
     142             :       fd_pubkey_t        authorized_withdrawer;
     143             :       uchar              commission;
     144             :       ulong              votes_cnt;
     145             :       fd_vote_acc_vote_t votes[31]; /* variable-length */
     146             :       /* uchar root_option */
     147             :       /* ulong root */
     148             :     } v3;
     149             : 
     150             :     struct __attribute__((packed)) {
     151             :       fd_pubkey_t     node_pubkey;
     152             :       fd_pubkey_t     authorized_withdrawer;
     153             :       fd_pubkey_t     inflation_rewards_collector;
     154             :       fd_pubkey_t     block_revenue_collector;
     155             :       ushort          inflation_rewards_commission_bps;
     156             :       ushort          block_revenue_commission_bps;
     157             :       ulong           pending_delegator_rewards;
     158             :       uchar           has_bls_pubkey_compressed;
     159             :       uchar           bls_pubkey_compressed[48];
     160             :       /* ulong              votes_cnt; */
     161             :       /* fd_vote_acc_vote_t votes[31]; */
     162             :       /* uchar root_option */
     163             :       /* ulong root */
     164             :     } v4;
     165             :   };
     166             : };
     167             : typedef struct fd_vote_acc fd_vote_acc_t;
     168             : 
     169             : /* fd_vote_acc_desc is a lightweight vote account descriptor for zero-
     170             :    copy inspection of a vote account. */
     171             : 
     172             : struct fd_vote_acc_desc {
     173             :   int    kind;        /* FD_VOTE_ACC_* */
     174             :   ushort votes_off;   /* offset to vote array */
     175             :   uchar  vote_cnt;    /* number of votes (max FD_TOWER_VOTE_MAX) */
     176             :   uchar  vote_stride; /* byte stride between votes */
     177             :   ulong  root_slot;   /* ULONG_MAX if not set */
     178             : };
     179             : typedef struct fd_vote_acc_desc fd_vote_acc_desc_t;
     180             : 
     181             : FD_PROTOTYPES_BEGIN
     182             : 
     183             : /* fd_vote_acc_desc recovers offsets to vote account bits given
     184             :    serialized data.  Does minimal input validation.  Initializes *desc
     185             :    and returns desc on success, or NULL on failure (invalid or
     186             :    unsupported vote account data). */
     187             : 
     188             : fd_vote_acc_desc_t *
     189             : fd_vote_acc_desc( fd_vote_acc_desc_t * desc,
     190             :                   uchar const *        data,
     191             :                   ulong                data_sz );
     192             : 
     193             : /* fd_vote_acc_desc_vote returns a pointer to a vote in a serialized
     194             :    vote account.  The return type depends on desc->kind:
     195             :    - FD_VOTE_ACC_V2 -> fd_vote_acc_vote_v2_t
     196             :    - FD_VOTE_ACC_V3 -> fd_vote_acc_vote_t
     197             :    - FD_VOTE_ACC_V4 -> fd_vote_acc_vote_t */
     198             : 
     199             : FD_FN_PURE static inline void const *
     200             : fd_vote_acc_desc_vote( fd_vote_acc_desc_t const * desc,
     201             :                        uchar const *              data,
     202           0 :                        ulong                      idx ) {
     203           0 :   return data + desc->votes_off + idx*desc->vote_stride;
     204           0 : }
     205             : 
     206             : /* fd_txn_parse_simple_vote optionally extracts the decoded tower sync
     207             :    from a vote transaction. */
     208             : 
     209             : int
     210             : fd_txn_parse_simple_vote( fd_txn_t const *                txn,
     211             :                           uchar    const *                payload,
     212             :                           fd_compact_tower_sync_serde_t * opt_tower_sync );
     213             : 
     214             : FD_PROTOTYPES_END
     215             : 
     216             : #endif /* HEADER_fd_src_choreo_tower_fd_tower_serdes_h */

Generated by: LCOV version 1.14