Line data Source code
1 : #ifndef HEADER_fd_src_disco_keyguard_fd_keyswitch_public_h 2 : #define HEADER_fd_src_disco_keyguard_fd_keyswitch_public_h 3 : 4 : #include "../fd_disco_base.h" 5 : 6 : #include "../../flamenco/types/fd_types.h" 7 : 8 : /* A fd_keyswitch_public_t provides APIs for out-of-band switching of 9 : the key of a validator. */ 10 : 11 12 : #define FD_KEYSWITCH_ALIGN (128UL) 12 12 : #define FD_KEYSWITCH_FOOTPRINT (128UL) 13 : 14 0 : #define FD_KEYSWITCH_MAGIC (0xf17eda2c37830000UL) /* firedancer ks ver 0 */ 15 : 16 0 : #define FD_KEYSWITCH_STATE_UNLOCKED (0UL) 17 : #define FD_KEYSWITCH_STATE_LOCKED (1UL) 18 0 : #define FD_KEYSWITCH_STATE_SWITCH_PENDING (2UL) 19 0 : #define FD_KEYSWITCH_STATE_UNHALT_PENDING (3UL) 20 0 : #define FD_KEYSWITCH_STATE_FAILED (4UL) 21 0 : #define FD_KEYSWITCH_STATE_COMPLETED (5UL) 22 : 23 : 24 : struct __attribute__((aligned(FD_KEYSWITCH_ALIGN))) fd_keyswitch_private { 25 : ulong magic; /* ==FD_KEYSWITCH_MAGIC */ 26 : ulong state; 27 : ulong result; 28 : ulong param; 29 : uchar bytes[ 64UL ]; 30 : /* Padding to FD_KEYSWITCH_ALIGN here */ 31 : }; 32 : 33 : typedef struct fd_keyswitch_private fd_keyswitch_t; 34 : 35 : FD_PROTOTYPES_BEGIN 36 : 37 : /* fd_keyswitch_{align,footprint} return the required alignment and 38 : footprint of a memory region suitable for use as a keyswitch. 39 : fd_keyswitch_align returns FD_KEYSWITCH_ALIGN. */ 40 : 41 : FD_FN_CONST ulong 42 : fd_keyswitch_align( void ); 43 : 44 : FD_FN_CONST ulong 45 : fd_keyswitch_footprint( void ); 46 : 47 : /* fd_keyswitch_new formats an unused memory region for use as a 48 : keyswitch. Assumes shmem is a non-NULL pointer to this region in the 49 : local address space with the required footprint and alignment. The 50 : keyswitch will be initialized to have the given state (should be in 51 : [0,UINT_MAX]). Returns shmem (and the memory region it points to 52 : will be formatted as a keyswitch, caller is not joined) and NULL on 53 : failure (logs details). Reasons for failure include an obviously bad 54 : shmem region. */ 55 : 56 : void * 57 : fd_keyswitch_new( void * shmem, 58 : ulong state ); 59 : 60 : /* fd_keyswitch_join joins the caller to the keyswitch. shks points to 61 : the first byte of the memory region backing the keyswitch in the 62 : caller's address space. Returns a pointer in the local address space 63 : to the keyswitch on success (this should not be assumed to be just a 64 : cast of shkc) or NULL on failure (logs details). Reasons for failure 65 : include the shkc is obviously not a local pointer to a memory region 66 : holding a keyswitch. Every successful join should have a matching 67 : leave. The lifetime of the join is until the matching leave or 68 : caller's thread group is terminated. */ 69 : 70 : fd_keyswitch_t * 71 : fd_keyswitch_join( void * shks ); 72 : 73 : /* fd_keyswitch_leave leaves a current local join. Returns a pointer to 74 : the underlying shared memory region on success (this should not be 75 : assumed to be just a cast of ks) and NULL on failure (logs details). 76 : Reasons for failure include ks is NULL. */ 77 : 78 : void * 79 : fd_keyswitch_leave( fd_keyswitch_t const * ks ); 80 : 81 : /* fd_keyswitch_delete unformats a memory region used as a keyswitch. 82 : Assumes nobody is joined to the region. Returns a pointer to the 83 : underlying shared memory region or NULL if used obviously in error 84 : (e.g. shks obviously does not point to a keyswitch ... logs details). 85 : The ownership of the memory region is transferred to the caller on 86 : success. */ 87 : 88 : void * 89 : fd_keyswitch_delete( void * shkc ); 90 : 91 : /* fd_keyswitch_state_query observes the current signal posted to the 92 : keyswitch. Assumes ks is a current local join. This is a compiler 93 : fence. Returns the current state on the ks at some point in time 94 : between when this was called and this returned. */ 95 : 96 : static inline ulong 97 0 : fd_keyswitch_state_query( fd_keyswitch_t const * ks ) { 98 0 : FD_COMPILER_MFENCE(); 99 0 : ulong s = FD_VOLATILE_CONST( ks->state ); 100 0 : FD_COMPILER_MFENCE(); 101 0 : return s; 102 0 : } 103 : 104 : /* fd_keyswitch_state_query observes the current param posted to the 105 : keyswitch. Assumes ks is a current local join. This is a compiler 106 : fence. Returns the current param on the ks at some point in time 107 : between when this was called and this returned. */ 108 : 109 : static inline ulong 110 0 : fd_keyswitch_param_query( fd_keyswitch_t const * ks ) { 111 0 : FD_COMPILER_MFENCE(); 112 0 : ulong s = FD_VOLATILE_CONST( ks->param ); 113 0 : FD_COMPILER_MFENCE(); 114 0 : return s; 115 0 : } 116 : 117 : /* fd_keyswitch_state atomically attempts to transition the ks from 118 : state before to state after. Assumes ks is a current local join and 119 : the caller is currently allowed to do a transition from before to 120 : after. Returns 0 if the transition succeeded, or 1 if it failed*/ 121 : 122 : static inline void 123 : fd_keyswitch_state( fd_keyswitch_t * ks, 124 0 : ulong s ) { 125 0 : FD_COMPILER_MFENCE(); 126 0 : FD_VOLATILE( ks->state ) = s; 127 0 : FD_COMPILER_MFENCE(); 128 0 : } 129 : 130 : FD_PROTOTYPES_END 131 : 132 : #endif /* HEADER_fd_src_disco_keyguard_fd_keyswitch_h */