Line data Source code
1 : #ifndef HEADER_fd_src_flamenco_accdb_fd_accdb_lineage_h 2 : #define HEADER_fd_src_flamenco_accdb_fd_accdb_lineage_h 3 : 4 : /* fd_accdb_lineage.h provides an API for filtering account database 5 : records by fork graph lineage. */ 6 : 7 : #include "../../funk/fd_funk_txn.h" 8 : 9 : /* FD_ACCDB_DEPTH_MAX specifies the max non-rooted fork depth. 10 : FIXME removing this limit is important for outage resilience */ 11 : 12 462 : #define FD_ACCDB_DEPTH_MAX (128UL) 13 : 14 : struct fd_accdb_lineage { 15 : 16 : /* Current fork cache */ 17 : fd_funk_txn_xid_t fork[ FD_ACCDB_DEPTH_MAX ]; 18 : ulong fork_depth; 19 : 20 : uint txn_idx[ FD_ACCDB_DEPTH_MAX ]; 21 : 22 : /* Current funk txn cache */ 23 : ulong tip_txn_idx; /* ==ULONG_MAX if tip is root */ 24 : 25 : }; 26 : 27 : typedef struct fd_accdb_lineage fd_accdb_lineage_t; 28 : 29 : FD_PROTOTYPES_BEGIN 30 : 31 : /* fd_accdb_lineage_has_xid returns 1 if the given record XID is part of 32 : the current lineage, otherwise 0. */ 33 : 34 : FD_FN_UNUSED static int 35 : fd_accdb_lineage_has_xid( fd_accdb_lineage_t const * lineage, 36 14511 : fd_funk_txn_xid_t const * rec_xid ) { 37 14511 : ulong const fork_depth = lineage->fork_depth; 38 15195 : for( ulong i=0UL; i<fork_depth; i++ ) { 39 15192 : if( fd_funk_txn_xid_eq( &lineage->fork[i], rec_xid ) ) return 1; 40 15192 : } 41 3 : return 0; 42 14511 : } 43 : 44 : /* fd_accdb_lineage_set_fork pivots the lineage object to the lineage 45 : from database root to the given XID (tip). */ 46 : 47 : void 48 : fd_accdb_lineage_set_fork_slow( fd_accdb_lineage_t * lineage, 49 : fd_funk_t const * funk, 50 : fd_funk_txn_xid_t const * xid ); 51 : 52 : static inline void 53 : fd_accdb_lineage_set_fork( fd_accdb_lineage_t * lineage, 54 : fd_funk_t const * funk, 55 42537 : fd_funk_txn_xid_t const * xid ) { 56 : /* Skip if already on the correct fork */ 57 42537 : if( FD_LIKELY( (!!lineage->fork_depth) & (!!fd_funk_txn_xid_eq( &lineage->fork[ 0 ], xid ) ) ) ) return; 58 201 : fd_accdb_lineage_set_fork_slow( lineage, funk, xid ); /* switch fork */ 59 201 : } 60 : 61 : /* fd_accdb_lineage_is_tip returns 1 if xid equals the tip of the 62 : current lineage, otherwise 0. */ 63 : 64 : static inline int 65 : fd_accdb_lineage_is_tip( fd_accdb_lineage_t const * lineage, 66 0 : fd_funk_txn_xid_t const * xid ) { 67 0 : if( lineage->fork_depth==0UL ) return 0; 68 0 : return fd_funk_txn_xid_eq( &lineage->fork[ 0 ], xid ); 69 0 : } 70 : 71 : /* fd_accdb_lineage_write_check verifies whether the tip of the current 72 : lineage is writable (not frozen). Aborts the app with FD_LOG_CRIT 73 : if writes to the tip of this lineage are not allowed. */ 74 : 75 : fd_funk_txn_t * 76 : fd_accdb_lineage_write_check( fd_accdb_lineage_t const * lineage, 77 : fd_funk_t const * funk ); 78 : 79 : FD_PROTOTYPES_END 80 : 81 : #endif /* HEADER_fd_src_flamenco_accdb_fd_accdb_lineage_h */