Line data Source code
1 : #include "fd_vote_queue.h"
2 : #include "../runtime/fd_hashes.h"
3 :
4 : /* Images kept by a memo slot (memo[i]!=NULL) are read from and hashed
5 : into the slot; others point into the account being stored (acc_cnt
6 : counts them). */
7 :
8 : struct __attribute__((aligned(FD_VOTE_QUEUE_ALIGN))) fd_vote_queue {
9 : fd_lthash_value_t delta[ 1 ];
10 : fd_lthash_value_t tmp [ FD_BLAKE3_XN_MAX ];
11 : ulong cnt;
12 : ulong acc_cnt;
13 : fd_footer_cache_memo_t * memo [ FD_BLAKE3_XN_MAX ];
14 : int sub [ FD_BLAKE3_XN_MAX ];
15 : uchar const * pk [ FD_BLAKE3_XN_MAX ];
16 : uchar const * ow [ FD_BLAKE3_XN_MAX ];
17 : ulong la [ FD_BLAKE3_XN_MAX ];
18 : int ex [ FD_BLAKE3_XN_MAX ];
19 : uchar const * da [ FD_BLAKE3_XN_MAX ];
20 : ulong dl [ FD_BLAKE3_XN_MAX ];
21 : fd_lthash_value_t * out [ FD_BLAKE3_XN_MAX ];
22 : };
23 :
24 : FD_STATIC_ASSERT( sizeof (fd_vote_queue_t)==FD_VOTE_QUEUE_FOOTPRINT, vote_queue_footprint );
25 : FD_STATIC_ASSERT( alignof(fd_vote_queue_t)==FD_VOTE_QUEUE_ALIGN, vote_queue_align );
26 :
27 : fd_vote_queue_t *
28 0 : fd_vote_queue_init( void * mem ) {
29 0 : fd_vote_queue_t * q = (fd_vote_queue_t *)mem;
30 0 : q->cnt = 0UL;
31 0 : q->acc_cnt = 0UL;
32 0 : fd_lthash_zero( q->delta );
33 0 : return q;
34 0 : }
35 :
36 : static void
37 0 : hash( fd_vote_queue_t * q ) {
38 0 : fd_hashes_account_lthash_xn( q->cnt, q->pk, q->ow, q->la, q->ex, q->da, q->dl, q->out );
39 0 : for( ulong i=0UL; i<q->cnt; i++ ) {
40 0 : if( q->sub[ i ] ) fd_lthash_sub( q->delta, q->out[ i ] );
41 0 : else fd_lthash_add( q->delta, q->out[ i ] );
42 0 : }
43 0 : q->cnt = 0UL;
44 0 : q->acc_cnt = 0UL;
45 0 : }
46 :
47 : static void
48 : push( fd_vote_queue_t * q,
49 : fd_footer_cache_memo_t * memo,
50 : int sub,
51 : uchar const * pubkey,
52 : uchar const * owner,
53 : ulong lamports,
54 : int executable,
55 : uchar const * data,
56 0 : ulong data_len ) {
57 0 : ulong i = q->cnt++;
58 0 : q->memo[ i ] = memo;
59 0 : q->sub [ i ] = sub;
60 0 : q->pk [ i ] = pubkey; q->ow[ i ] = owner; q->la[ i ] = lamports;
61 0 : q->ex [ i ] = executable; q->da[ i ] = data; q->dl[ i ] = data_len;
62 0 : q->out [ i ] = memo ? &memo->lthash : q->tmp+i;
63 0 : q->acc_cnt += !memo;
64 0 : if( q->cnt==FD_BLAKE3_XN_MAX ) hash( q );
65 0 : }
66 :
67 : void
68 : fd_vote_queue_store( fd_vote_queue_t * q,
69 : fd_acc_t const * acc,
70 0 : fd_footer_cache_memo_t * memo ) {
71 0 : for( ulong i=0UL; memo && i<q->cnt; i++ ) {
72 0 : if( FD_UNLIKELY( q->memo[ i ]==memo ) ) { hash( q ); break; } /* memo's waiting image */
73 0 : }
74 :
75 0 : fd_lthash_value_t const * pre = memo ? fd_footer_cache_memo_query( memo, acc->pubkey, acc->prior_owner, acc->prior_lamports, acc->prior_executable, acc->prior_data, acc->prior_data_len ) : NULL;
76 0 : if( pre ) fd_lthash_sub( q->delta, pre ); /* before the slot is overwritten */
77 0 : else push( q, NULL, 1, acc->pubkey, acc->prior_owner, acc->prior_lamports, acc->prior_executable, acc->prior_data, acc->prior_data_len );
78 :
79 0 : int kept = memo && fd_footer_cache_memo_insert( memo, acc->pubkey, acc->owner, acc->lamports, acc->executable, acc->data, acc->data_len );
80 0 : FD_TEST( kept || !pre ); /* a hit's prior image fit */
81 0 : if( kept ) push( q, memo, 0, memo->pubkey, memo->owner, memo->lamports, memo->executable, memo->data, memo->data_len );
82 0 : else push( q, NULL, 0, acc->pubkey, acc->owner, acc->lamports, acc->executable, acc->data, acc->data_len );
83 :
84 0 : if( q->acc_cnt ) hash( q );
85 0 : }
86 :
87 : fd_lthash_value_t const *
88 0 : fd_vote_queue_fini( fd_vote_queue_t * q ) {
89 0 : if( q->cnt ) hash( q );
90 0 : return q->delta;
91 0 : }
|