Skip to content

Commit 822d33d

Browse files
yufeng-jumpmmcgee-jump
authored andcommitted
txncache: fix short copy
A short copy would leak txnpages. Moreover, when more than one txnpage is copied at once, copying uints into ushorts would cause txnpage 0 to be considered free when it it not, as the upper ushort of a uint would be all zeroes in the case of a valid txnpage index.
1 parent 4b729b6 commit 822d33d

File tree

2 files changed

+34
-34
lines changed

2 files changed

+34
-34
lines changed

src/flamenco/runtime/fd_txncache.c

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ struct blockcache {
88
uint * heads; /* The hash table for the blockhash. Each entry is a pointer to the head of a linked list of
99
transactions that reference this blockhash. As we add transactions to the bucket, the head
1010
pointer is updated to the new item, and the new item is pointed to the previous head. */
11-
uint * pages; /* A list of the txnpages containing the transactions for this blockcache. */
11+
ushort * pages; /* A list of the txnpages containing the transactions for this blockcache. */
1212

1313
descends_set_t * descends; /* Each fork can descend from other forks in the txncache, and this bit vector contains one
1414
value for each fork in the txncache. If this fork descends from some other fork F, then
@@ -74,14 +74,14 @@ fd_txncache_new( void * ljoin,
7474
}
7575

7676
FD_SCRATCH_ALLOC_INIT( l, shmem );
77-
fd_txncache_shmem_t * tc = FD_SCRATCH_ALLOC_APPEND( l, FD_TXNCACHE_SHMEM_ALIGN, sizeof(fd_txncache_shmem_t) );
78-
void * _blockhash_map = FD_SCRATCH_ALLOC_APPEND( l, blockhash_map_align(), blockhash_map_footprint( blockhash_map_chains ) );
79-
void * _blockcache_pool = FD_SCRATCH_ALLOC_APPEND( l, blockcache_pool_align(), blockcache_pool_footprint( max_active_slots ) );
80-
void * _blockcache_pages = FD_SCRATCH_ALLOC_APPEND( l, alignof(uint), max_active_slots*_max_txnpages_per_blockhash*sizeof(uint) );
81-
void * _blockcache_heads = FD_SCRATCH_ALLOC_APPEND( l, alignof(uint), max_active_slots*shmem->txn_per_slot_max*sizeof(uint) );
82-
void * _blockcache_descends = FD_SCRATCH_ALLOC_APPEND( l, descends_set_align(), max_active_slots*_descends_footprint );
83-
void * _txnpages_free = FD_SCRATCH_ALLOC_APPEND( l, alignof(ushort), _max_txnpages*sizeof(ushort) );
84-
void * _txnpages = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_txncache_txnpage_t), _max_txnpages*sizeof(fd_txncache_txnpage_t) );
77+
fd_txncache_shmem_t * tc = FD_SCRATCH_ALLOC_APPEND( l, FD_TXNCACHE_SHMEM_ALIGN, sizeof(fd_txncache_shmem_t) );
78+
void * _blockhash_map = FD_SCRATCH_ALLOC_APPEND( l, blockhash_map_align(), blockhash_map_footprint( blockhash_map_chains ) );
79+
void * _blockcache_pool = FD_SCRATCH_ALLOC_APPEND( l, blockcache_pool_align(), blockcache_pool_footprint( max_active_slots ) );
80+
void * _blockcache_pages = FD_SCRATCH_ALLOC_APPEND( l, alignof(ushort), max_active_slots*_max_txnpages_per_blockhash*sizeof(ushort) );
81+
void * _blockcache_heads = FD_SCRATCH_ALLOC_APPEND( l, alignof(uint), max_active_slots*shmem->txn_per_slot_max*sizeof(uint) );
82+
void * _blockcache_descends = FD_SCRATCH_ALLOC_APPEND( l, descends_set_align(), max_active_slots*_descends_footprint );
83+
void * _txnpages_free = FD_SCRATCH_ALLOC_APPEND( l, alignof(ushort), _max_txnpages*sizeof(ushort) );
84+
void * _txnpages = FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_txncache_txnpage_t), _max_txnpages*sizeof(fd_txncache_txnpage_t) );
8585

8686
FD_SCRATCH_ALLOC_INIT( l2, ljoin );
8787
fd_txncache_t * ltc = FD_SCRATCH_ALLOC_APPEND( l2, FD_TXNCACHE_ALIGN, sizeof(fd_txncache_t) );
@@ -93,7 +93,7 @@ fd_txncache_new( void * ljoin,
9393
ltc->blockcache_shmem_pool = blockcache_pool_join( _blockcache_pool );
9494

9595
for( ulong i=0UL; i<shmem->active_slots_max; i++ ) {
96-
ltc->blockcache_pool[ i ].pages = (uint *)_blockcache_pages + i*_max_txnpages_per_blockhash;
96+
ltc->blockcache_pool[ i ].pages = (ushort *)_blockcache_pages + i*_max_txnpages_per_blockhash;
9797
ltc->blockcache_pool[ i ].heads = (uint *)_blockcache_heads + i*shmem->txn_per_slot_max;
9898
ltc->blockcache_pool[ i ].descends = descends_set_join( (uchar *)_blockcache_descends + i*_descends_footprint );
9999
ltc->blockcache_pool[ i ].shmem = ltc->blockcache_shmem_pool + i;
@@ -151,13 +151,13 @@ fd_txncache_ensure_txnpage( fd_txncache_t * tc,
151151
if( FD_UNLIKELY( page_cnt>tc->shmem->txnpages_per_blockhash_max ) ) return NULL;
152152

153153
if( FD_LIKELY( page_cnt ) ) {
154-
uint txnpage_idx = blockcache->pages[ page_cnt-1 ];
154+
ushort txnpage_idx = blockcache->pages[ page_cnt-1 ];
155155
ushort txnpage_free = tc->txnpages[ txnpage_idx ].free;
156156
if( FD_LIKELY( txnpage_free ) ) return &tc->txnpages[ txnpage_idx ];
157157
}
158158

159159
if( FD_UNLIKELY( page_cnt==tc->shmem->txnpages_per_blockhash_max ) ) return NULL;
160-
if( FD_LIKELY( FD_ATOMIC_CAS( &blockcache->pages[ page_cnt ], UINT_MAX, UINT_MAX-1UL )==UINT_MAX ) ) {
160+
if( FD_LIKELY( FD_ATOMIC_CAS( &blockcache->pages[ page_cnt ], (ushort)USHORT_MAX, (ushort)(USHORT_MAX-1UL) )==(ushort)USHORT_MAX ) ) {
161161
ulong txnpages_free_cnt = tc->shmem->txnpages_free_cnt;
162162
for(;;) {
163163
if( FD_UNLIKELY( !txnpages_free_cnt ) ) return NULL;
@@ -176,8 +176,8 @@ fd_txncache_ensure_txnpage( fd_txncache_t * tc,
176176
blockcache->shmem->pages_cnt = (ushort)(page_cnt+1);
177177
return txnpage;
178178
} else {
179-
uint txnpage_idx = blockcache->pages[ page_cnt ];
180-
while( FD_UNLIKELY( txnpage_idx>=UINT_MAX-1UL ) ) {
179+
ushort txnpage_idx = blockcache->pages[ page_cnt ];
180+
while( FD_UNLIKELY( txnpage_idx>=USHORT_MAX-1UL ) ) {
181181
txnpage_idx = blockcache->pages[ page_cnt ];
182182
FD_SPIN_PAUSE();
183183
}
@@ -259,7 +259,7 @@ fd_txncache_attach_child( fd_txncache_t * tc,
259259
fork->shmem->frozen = 0;
260260
memset( fork->heads, 0xFF, tc->shmem->txn_per_slot_max*sizeof(uint) );
261261
fork->shmem->pages_cnt = 0;
262-
memset( fork->pages, 0xFF, tc->shmem->txnpages_per_blockhash_max*sizeof(uint) );
262+
memset( fork->pages, 0xFF, tc->shmem->txnpages_per_blockhash_max*sizeof(fork->pages[ 0 ]) );
263263

264264
fd_rwlock_unwrite( tc->shmem->lock );
265265
return fork_id;
@@ -304,7 +304,7 @@ fd_txncache_finalize_fork( fd_txncache_t * tc,
304304
static inline void
305305
remove_blockcache( fd_txncache_t * tc,
306306
blockcache_t * blockcache ) {
307-
memcpy( tc->txnpages_free+tc->shmem->txnpages_free_cnt, blockcache->pages, blockcache->shmem->pages_cnt*sizeof(ushort) );
307+
memcpy( tc->txnpages_free+tc->shmem->txnpages_free_cnt, blockcache->pages, blockcache->shmem->pages_cnt*sizeof(tc->txnpages_free[ 0 ]) );
308308
tc->shmem->txnpages_free_cnt = (ushort)(tc->shmem->txnpages_free_cnt+blockcache->shmem->pages_cnt);
309309

310310
ulong idx = blockcache_pool_idx( tc->blockcache_shmem_pool, blockcache->shmem );

src/flamenco/runtime/fd_txncache_shmem.c

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ fd_txncache_max_txnpages_per_blockhash( ulong max_active_slots,
3838
the same blockhash. */
3939

4040
ulong result = 1UL+(max_txn_per_slot*max_active_slots)/FD_TXNCACHE_TXNS_PER_PAGE;
41-
if( FD_UNLIKELY( result>USHORT_MAX ) ) return 0;
41+
if( FD_UNLIKELY( result>USHORT_MAX-2UL ) ) return 0; /* MAX is the invalid flag, MAX-1 is the xbusy flag. */
4242
return (ushort)result;
4343
}
4444

@@ -62,7 +62,7 @@ fd_txncache_max_txnpages( ulong max_active_slots,
6262
pages, and the other blockhashes need 1 page each. */
6363

6464
ulong result = max_active_slots-1UL+max_active_slots*(1UL+(max_txn_per_slot-1UL)/FD_TXNCACHE_TXNS_PER_PAGE);
65-
if( FD_UNLIKELY( result>USHORT_MAX ) ) return 0;
65+
if( FD_UNLIKELY( result>USHORT_MAX-2UL ) ) return 0; /* MAX is the invalid flag, MAX-1 is the xbusy flag. */
6666
return (ushort)result;
6767
}
6868

@@ -93,14 +93,14 @@ fd_txncache_shmem_footprint( ulong max_live_slots,
9393

9494
ulong l;
9595
l = FD_LAYOUT_INIT;
96-
l = FD_LAYOUT_APPEND( l, FD_TXNCACHE_SHMEM_ALIGN, sizeof(fd_txncache_shmem_t) );
97-
l = FD_LAYOUT_APPEND( l, blockhash_map_align(), blockhash_map_footprint( blockhash_map_chains ) );
98-
l = FD_LAYOUT_APPEND( l, blockcache_pool_align(), blockcache_pool_footprint( max_active_slots ) );
99-
l = FD_LAYOUT_APPEND( l, alignof(uint), max_active_slots*_max_txnpages_per_blockhash*sizeof(uint) ); /* blockcache->pages */
100-
l = FD_LAYOUT_APPEND( l, alignof(uint), max_active_slots*max_txn_per_slot*sizeof(uint) ); /* blockcache->heads */
101-
l = FD_LAYOUT_APPEND( l, descends_set_align(), max_active_slots*_descends_footprint ); /* blockcache->descends */
102-
l = FD_LAYOUT_APPEND( l, alignof(ushort), _max_txnpages*sizeof(ushort) ); /* txnpages_free */
103-
l = FD_LAYOUT_APPEND( l, alignof(fd_txncache_txnpage_t), _max_txnpages*sizeof(fd_txncache_txnpage_t) ); /* txnpages */
96+
l = FD_LAYOUT_APPEND( l, FD_TXNCACHE_SHMEM_ALIGN, sizeof(fd_txncache_shmem_t) );
97+
l = FD_LAYOUT_APPEND( l, blockhash_map_align(), blockhash_map_footprint( blockhash_map_chains ) );
98+
l = FD_LAYOUT_APPEND( l, blockcache_pool_align(), blockcache_pool_footprint( max_active_slots ) );
99+
l = FD_LAYOUT_APPEND( l, alignof(ushort), max_active_slots*_max_txnpages_per_blockhash*sizeof(ushort) ); /* blockcache->pages */
100+
l = FD_LAYOUT_APPEND( l, alignof(uint), max_active_slots*max_txn_per_slot*sizeof(uint) ); /* blockcache->heads */
101+
l = FD_LAYOUT_APPEND( l, descends_set_align(), max_active_slots*_descends_footprint ); /* blockcache->descends */
102+
l = FD_LAYOUT_APPEND( l, alignof(ushort), _max_txnpages*sizeof(ushort) ); /* txnpages_free */
103+
l = FD_LAYOUT_APPEND( l, alignof(fd_txncache_txnpage_t), _max_txnpages*sizeof(fd_txncache_txnpage_t) ); /* txnpages */
104104
return FD_LAYOUT_FINI( l, FD_TXNCACHE_SHMEM_ALIGN );
105105
}
106106

@@ -134,14 +134,14 @@ fd_txncache_shmem_new( void * shmem,
134134
if( FD_UNLIKELY( !_descends_footprint ) ) return NULL;
135135

136136
FD_SCRATCH_ALLOC_INIT( l, shmem );
137-
fd_txncache_shmem_t * tc = FD_SCRATCH_ALLOC_APPEND( l, FD_TXNCACHE_SHMEM_ALIGN, sizeof(fd_txncache_shmem_t) );
138-
void * _blockhash_map = FD_SCRATCH_ALLOC_APPEND( l, blockhash_map_align(), blockhash_map_footprint( blockhash_map_chains ) );
139-
void * _blockcache_pool = FD_SCRATCH_ALLOC_APPEND( l, blockcache_pool_align(), blockcache_pool_footprint( max_active_slots ) );
140-
FD_SCRATCH_ALLOC_APPEND( l, alignof(uint), max_active_slots*_max_txnpages_per_blockhash*sizeof(uint) );
141-
FD_SCRATCH_ALLOC_APPEND( l, alignof(uint), max_active_slots*max_txn_per_slot*sizeof(uint) );
142-
void * _blockcache_descends = FD_SCRATCH_ALLOC_APPEND( l, descends_set_align(), max_active_slots*_descends_footprint );
143-
void * _txnpages_free = FD_SCRATCH_ALLOC_APPEND( l, alignof(ushort), _max_txnpages*sizeof(ushort) );
144-
FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_txncache_txnpage_t), _max_txnpages*sizeof(fd_txncache_txnpage_t) );
137+
fd_txncache_shmem_t * tc = FD_SCRATCH_ALLOC_APPEND( l, FD_TXNCACHE_SHMEM_ALIGN, sizeof(fd_txncache_shmem_t) );
138+
void * _blockhash_map = FD_SCRATCH_ALLOC_APPEND( l, blockhash_map_align(), blockhash_map_footprint( blockhash_map_chains ) );
139+
void * _blockcache_pool = FD_SCRATCH_ALLOC_APPEND( l, blockcache_pool_align(), blockcache_pool_footprint( max_active_slots ) );
140+
FD_SCRATCH_ALLOC_APPEND( l, alignof(ushort), max_active_slots*_max_txnpages_per_blockhash*sizeof(ushort) );
141+
FD_SCRATCH_ALLOC_APPEND( l, alignof(uint), max_active_slots*max_txn_per_slot*sizeof(uint) );
142+
void * _blockcache_descends = FD_SCRATCH_ALLOC_APPEND( l, descends_set_align(), max_active_slots*_descends_footprint );
143+
void * _txnpages_free = FD_SCRATCH_ALLOC_APPEND( l, alignof(ushort), _max_txnpages*sizeof(ushort) );
144+
FD_SCRATCH_ALLOC_APPEND( l, alignof(fd_txncache_txnpage_t), _max_txnpages*sizeof(fd_txncache_txnpage_t) );
145145

146146
fd_txncache_blockcache_shmem_t * blockcache_pool = blockcache_pool_join( blockcache_pool_new( _blockcache_pool, max_active_slots ) );
147147
FD_TEST( blockcache_pool );

0 commit comments

Comments
 (0)