LCOV - code coverage report
Current view: top level - ballet/txn - fd_txn_build.h (source / functions) Hit Total Coverage
Test: cov.lcov Lines: 0 19 0.0 %
Date: 2026-07-09 05:37:44 Functions: 0 12 0.0 %

          Line data    Source code
       1             : #ifndef HEADER_fd_src_ballet_txn_fd_txn_build_h
       2             : #define HEADER_fd_src_ballet_txn_fd_txn_build_h
       3             : 
       4             : /* fd_txn_build.h is an API to procedurally build Solana transactions
       5             :    from instructions (program invocations). */
       6             : 
       7             : #include "fd_txn.h"
       8             : #include "../../disco/fd_txn_p.h"
       9             : #include "../../flamenco/accdb/fd_accdb.h"
      10             : 
      11             : /* The fd_txn_builder_t class provides methods for assembling a txn.
      12             :    fd_txn_builder_t is a static size struct, so a local declaration is a
      13             :    valid way to reserve memory for a txn_builder object:
      14             : 
      15             :      fd_txn_builder_t builder[1];
      16             :      fd_txn_builder_new( builder );
      17             :      ... */
      18             : 
      19             : struct fd_txn_b_acct {
      20             :   fd_acct_addr_t key;
      21             : 
      22             :   uchar cat;
      23             :   uchar map_next;
      24             : 
      25             :   uchar alut_i; /* idx of ALUT account */
      26             :   uint  alut_j; /* idx within ALUT account */
      27             : };
      28             : typedef struct fd_txn_b_acct fd_txn_b_acct_t;
      29             : 
      30             : struct fd_txn_b_instr {
      31             :   uchar  program_id;
      32             :   uchar  instr_acct0;
      33             :   uchar  instr_acct_cnt;
      34             :   ushort data_off;
      35             :   ushort data_sz;
      36             : };
      37             : typedef struct fd_txn_b_instr fd_txn_b_instr_t;
      38             : 
      39             : /* Declare a separately-chained hashmap of instruction accounts */
      40             : 
      41             : #define MAP_NAME          fd_txn_b_addr_map
      42             : #define MAP_ELE_T         fd_txn_b_acct_t
      43           0 : #define MAP_IDX_T         uchar
      44             : #define MAP_KEY_T         fd_acct_addr_t
      45           0 : #define MAP_KEY_EQ(a,b)   0==memcmp( a, b, sizeof(fd_acct_addr_t) )
      46           0 : #define MAP_KEY_HASH(k,s) fd_accdb_hash( (k)->b, (s) )
      47           0 : #define MAP_NEXT  map_next
      48             : #include "../../util/tmpl/fd_map_chain.c"
      49             : #define FD_TXN_B_ADDR_CHAIN_CNT (2*FD_TXN_ACCT_ADDR_MAX)
      50             : #define FD_TXN_B_ADDR_MAP_SZ    (sizeof(fd_txn_b_addr_map_t) + FD_TXN_B_ADDR_CHAIN_CNT)
      51             : 
      52             : struct fd_txn_builder {
      53             : 
      54             :   /* Misc fields */
      55             :   fd_acct_addr_t recent_blockhash;
      56             :   uchar fee_payer_acct;
      57             : 
      58             :   /* Flags */
      59             :   uchar fee_payer_set  : 1;
      60             :   uchar alut_set       : 1;
      61             : 
      62             :   /* ALUT */
      63             :   uchar alut_i; /* current ALUT account, UCHAR_MAX if none open */
      64             : 
      65             :   /* Instructions */
      66             :   fd_txn_b_instr_t instr[ FD_TXN_INSTR_MAX ];
      67             :   uchar            instr_cnt;
      68             : 
      69             :   /* Transaction Accounts */
      70             :   fd_txn_b_acct_t acct    [ FD_TXN_ACCT_ADDR_MAX ];
      71             :   uchar           acct_map[ FD_TXN_ACCT_ADDR_MAX ];
      72             :   uchar           acct_rev[ FD_TXN_ACCT_ADDR_MAX ];
      73             :   uchar           acct_cnt;
      74             : 
      75             :   /* Instruction Account Pool */
      76             :   uchar instr_acct[ FD_TXN_ACCT_ADDR_MAX ];
      77             :   uchar instr_acct_cnt;
      78             : 
      79             :   /* Address Hash Map */
      80             :   union {
      81             :     fd_txn_b_addr_map_t map;
      82             :     uchar               map_mem[ FD_TXN_B_ADDR_MAP_SZ ];
      83             :   };
      84             : 
      85             :   /* Bump allocator for instruction datas */
      86             : #define FD_TXN_B_DATA_BUMP_MAX FD_TXN_MTU
      87             :   uchar  data_bump[ FD_TXN_B_DATA_BUMP_MAX ];
      88             :   ushort data_bump_sz;
      89             : 
      90             : };
      91             : typedef struct fd_txn_builder fd_txn_builder_t;
      92             : 
      93             : FD_PROTOTYPES_BEGIN
      94             : 
      95             : /* Constructors *******************************************************/
      96             : 
      97             : fd_txn_builder_t *
      98             : fd_txn_builder_new( fd_txn_builder_t * mem,
      99             :                     ulong              seed );
     100             : 
     101             : void *
     102             : fd_txn_builder_delete( fd_txn_builder_t * builder );
     103             : 
     104             : FD_FN_UNUSED static fd_txn_builder_t *
     105           0 : fd_txn_builder_reset( fd_txn_builder_t * builder ) {
     106           0 :   ulong const seed = builder->map.seed;
     107           0 :   fd_txn_builder_delete( builder );
     108           0 :   return fd_txn_builder_new( builder, seed );
     109           0 : }
     110             : 
     111             : /* Miscellaneous fields ***********************************************/
     112             : 
     113             : /* fd_txn_builder_fee_payer_set sets the transaction's fee payer. */
     114             : 
     115             : fd_txn_builder_t *
     116             : fd_txn_builder_fee_payer_set( fd_txn_builder_t * builder,
     117             :                               void const *       fee_payer );
     118             : 
     119             : /* fd_txn_builder_blockhash_set sets the transaction's "recent block
     120             :    hash" field. */
     121             : 
     122             : static inline void
     123             : fd_txn_builder_blockhash_set( fd_txn_builder_t * builder,
     124           0 :                               void const *       blockhash ) {
     125           0 :   memcpy( &builder->recent_blockhash, blockhash, sizeof(fd_acct_addr_t) );
     126           0 : }
     127             : 
     128             : /* fd_txn_builder_nonce_set sets the transaction's nonce account (by
     129             :    making the first instruction a "system program advance nonce"
     130             :    instruction).  This is only useful in combination with
     131             :    fd_txn_builder_blockhash_set( builder, nonce_hash ).  Must be called
     132             :    before fd_txn_builder_instr_open.  May not be called multiple times. */
     133             : 
     134             : fd_txn_builder_t *
     135             : fd_txn_builder_nonce_set( fd_txn_builder_t * builder,
     136             :                           void const *       nonce_account,
     137             :                           void const *       nonce_authority );
     138             : 
     139             : /* Transaction Instructions *******************************************/
     140             : 
     141             : /* fd_txn_builder_instr_open starts building an instruction.  Returns
     142             :    builder on success, NULL on failure. */
     143             : 
     144             : fd_txn_builder_t *
     145             : fd_txn_builder_instr_open( fd_txn_builder_t * builder,
     146             :                            void const *       program_id,
     147             :                            void const *       data,
     148             :                            ulong              data_sz );
     149             : 
     150             : /* fd_txn_builder_instr_account_push appends an instruction account to
     151             :    the instruction being built.  acct_cat is a bitwise-OR of any of
     152             :    FD_TXN_ACCT_CAT_{WRITABLE,SIGNER}.  acct_cat==0 is fine and implies
     153             :    a readonly account access. */
     154             : 
     155             : fd_txn_builder_t *
     156             : fd_txn_builder_instr_account_push(
     157             :     fd_txn_builder_t * builder,
     158             :     void const *       acct_addr,
     159             :     uint               acct_cat
     160             : );
     161             : 
     162             : /* fd_txn_builder_instr_close finishes building an instruction. */
     163             : 
     164             : void
     165             : fd_txn_builder_instr_close( fd_txn_builder_t * builder );
     166             : 
     167             : /* FIXME add compute budget / priority fee instructions */
     168             : 
     169             : /* Address Lookup Tables **********************************************/
     170             : 
     171             : /* fd_txn_builder_alut_open adds an address lookup table (ALUT) to the
     172             :    txn builder, which acts like a dictionary for account addresses.
     173             :    This helps reduce serialized transaction size.  alut_addr is the
     174             :    account address of the ALUT.
     175             : 
     176             :    ALUTs should only be registered with the builder once the caller is
     177             :    done adding instructions. */
     178             : 
     179             : fd_txn_builder_t *
     180             : fd_txn_builder_alut_open( fd_txn_builder_t * builder,
     181             :                           void const *       alut_addr );
     182             : 
     183             : /* fd_txn_builder_alut_address_push registers an ALUT address entry with
     184             :    the transaction builder.  acct_addr is the address referenced by the
     185             :    ALUT, acct_idx is the index of that address within the ALUT.  If the
     186             :    acct_addr is used by any instruction, it is replaced with an ALUT
     187             :    reference, if possible.  acct_addr that are not used or cannot be
     188             :    referenced using ALUT (e.g. because it is also in use as a program
     189             :    ID) are silently ignored.  Safe to call multiple times for the same
     190             :    acct_addr/acct_idx (ignores subsequent calls), and accepts acct_idx
     191             :    in arbitrary order. */
     192             : 
     193             : void
     194             : fd_txn_builder_alut_address_push(
     195             :     fd_txn_builder_t * builder,
     196             :     void const *       acct_addr,
     197             :     uint               acct_idx
     198             : );
     199             : 
     200             : /* fd_txn_builder_alut_close finishes adding an ALUT. */
     201             : 
     202             : void
     203             : fd_txn_builder_alut_close( fd_txn_builder_t * builder );
     204             : 
     205             : /* Build Finish *******************************************************/
     206             : 
     207             : /* fd_txn_build_raw produces a serialized transaction object.
     208             :    Serializes the transaction to out and returns the byte size on
     209             :    success.  On failure returns 0 silently. */
     210             : 
     211             : uint
     212             : fd_txn_build_raw( fd_txn_builder_t * builder,
     213             :                   uchar              out[ FD_TXN_MTU ] );
     214             : 
     215             : /* fd_txn_build builds a transaction separately into a raw buffer and a
     216             :    fd_txn_t.  Serializes the transaction to out, populates out_txn,
     217             :    and returns the serialized byte size on success.  If opt_out_txn_t_sz
     218             :    !=NULL, sets *opt_out_txn_t_sz to the size of the out_txn object.
     219             :    The footprint of out_txn must be at least FD_TXN_MAX_SZ.  On failure
     220             :    returns 0 silently. */
     221             : 
     222             : uint
     223             : fd_txn_build( fd_txn_builder_t *  builder,
     224             :               uchar               out[ FD_TXN_MTU ],
     225             :               fd_txn_t * restrict out_txn,
     226             :               ushort *            opt_out_txn_t_sz );
     227             : 
     228             : /* fd_txn_build_p builds a transaction into a txn_p_t. */
     229             : 
     230             : FD_FN_UNUSED static uint
     231             : fd_txn_build_p( fd_txn_builder_t * builder,
     232           0 :                 fd_txn_p_t *       out ) {
     233           0 :   uint payload_sz = fd_txn_build( builder, out->payload, TXN( out ), NULL );
     234           0 :   out->payload_sz = (ushort)payload_sz;
     235           0 :   return payload_sz;
     236           0 : }
     237             : 
     238             : FD_PROTOTYPES_END
     239             : 
     240             : /* FD_TXN_ACCT_CAT_PIN prevents an ALUT demote.  For internal use only.
     241             :    Must not overlap with the flags in fd_txn.h */
     242           0 : #define FD_TXN_ACCT_CAT_PIN       0x40
     243           0 : #define FD_TXN_ACCT_CAT_FEE_PAYER 0x80
     244             : #define FD_TXN_ACCT_CAT_IS_PIN    (FD_TXN_ACCT_CAT_PIN|FD_TXN_ACCT_CAT_SIGNER|FD_TXN_ACCT_CAT_FEE_PAYER)
     245             : 
     246             : #endif /* HEADER_fd_src_ballet_txn_fd_txn_build_h */

Generated by: LCOV version 1.14