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 285 : #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 : /* Current funk txn cache */ 21 : ulong tip_txn_idx; /* ==ULONG_MAX if tip is root */ 22 : 23 : }; 24 : 25 : typedef struct fd_accdb_lineage fd_accdb_lineage_t; 26 : 27 : FD_PROTOTYPES_BEGIN 28 : 29 : /* fd_accdb_lineage_has_xid returns 1 if the given record XID is part of 30 : the current lineage, otherwise 0. */ 31 : 32 : FD_FN_UNUSED static int 33 : fd_accdb_lineage_has_xid( fd_accdb_lineage_t const * lineage, 34 13776 : fd_funk_txn_xid_t const * rec_xid ) { 35 13776 : ulong const fork_depth = lineage->fork_depth; 36 14079 : for( ulong i=0UL; i<fork_depth; i++ ) { 37 14076 : if( fd_funk_txn_xid_eq( &lineage->fork[i], rec_xid ) ) return 1; 38 14076 : } 39 3 : return 0; 40 13776 : } 41 : 42 : /* fd_accdb_lineage_set_fork pivots the lineage object to the lineage 43 : from database root to the given XID (tip). */ 44 : 45 : void 46 : fd_accdb_lineage_set_fork_slow( fd_accdb_lineage_t * lineage, 47 : fd_funk_t const * funk, 48 : fd_funk_txn_xid_t const * xid ); 49 : 50 : static inline void 51 : fd_accdb_lineage_set_fork( fd_accdb_lineage_t * lineage, 52 : fd_funk_t const * funk, 53 23703 : fd_funk_txn_xid_t const * xid ) { 54 : /* Skip if already on the correct fork */ 55 23703 : if( FD_LIKELY( (!!lineage->fork_depth) & (!!fd_funk_txn_xid_eq( &lineage->fork[ 0 ], xid ) ) ) ) return; 56 129 : fd_accdb_lineage_set_fork_slow( lineage, funk, xid ); /* switch fork */ 57 129 : } 58 : 59 : /* fd_accdb_lineage_is_tip returns 1 if xid equals the tip of the 60 : current lineage, otherwise 0. */ 61 : 62 : static inline int 63 : fd_accdb_lineage_is_tip( fd_accdb_lineage_t const * lineage, 64 0 : fd_funk_txn_xid_t const * xid ) { 65 0 : if( lineage->fork_depth==0UL ) return 0; 66 0 : return fd_funk_txn_xid_eq( &lineage->fork[ 0 ], xid ); 67 0 : } 68 : 69 : /* fd_accdb_lineage_write_check verifies whether the tip of the current 70 : lineage is writable (not frozen). Aborts the app with FD_LOG_CRIT 71 : if writes to the tip of this lineage are not allowed. */ 72 : 73 : fd_funk_txn_t * 74 : fd_accdb_lineage_write_check( fd_accdb_lineage_t const * lineage, 75 : fd_funk_t const * funk ); 76 : 77 : FD_PROTOTYPES_END 78 : 79 : #endif /* HEADER_fd_src_flamenco_accdb_fd_accdb_lineage_h */