@@ -90,19 +90,60 @@ delete_record(PaddedEndOffset, StoreID) ->
90
90
91
91
generate_missing_entropy (PaddedEndOffset , RewardAddr ) ->
92
92
Entropies = generate_entropies (RewardAddr , PaddedEndOffset , 0 ),
93
- EntropyIndex = ar_replica_2_9 :get_slice_index (PaddedEndOffset ),
94
- take_combined_entropy_by_index (Entropies , EntropyIndex ).
93
+ case Entropies of
94
+ {error , Reason } ->
95
+ {error , Reason };
96
+ _ ->
97
+ EntropyIndex = ar_replica_2_9 :get_slice_index (PaddedEndOffset ),
98
+ take_combined_entropy_by_index (Entropies , EntropyIndex )
99
+ end .
95
100
96
101
% % @doc Returns all the entropies needed to encipher the chunk at PaddedEndOffset.
97
- % % ar_packing_server:get_replica_2_9_entropy/3 will query a cached entropy, or generate it
98
- % % if it is not cached.
99
102
generate_entropies (_RewardAddr , _PaddedEndOffset , SubChunkStart )
100
103
when SubChunkStart == ? DATA_CHUNK_SIZE ->
101
104
[];
102
105
generate_entropies (RewardAddr , PaddedEndOffset , SubChunkStart ) ->
103
106
SubChunkSize = ? COMPOSITE_PACKING_SUB_CHUNK_SIZE ,
104
- [ar_packing_server :get_replica_2_9_entropy (RewardAddr , PaddedEndOffset , SubChunkStart )
105
- | generate_entropies (RewardAddr , PaddedEndOffset , SubChunkStart + SubChunkSize )].
107
+ EntropyTasks = lists :map (
108
+ fun (Offset ) ->
109
+ Ref = make_ref (),
110
+ ar_packing_server :request_entropy_generation (
111
+ Ref , self (), {RewardAddr , PaddedEndOffset , Offset }),
112
+ Ref
113
+ end ,
114
+ lists :seq (SubChunkStart , ? DATA_CHUNK_SIZE - SubChunkSize , SubChunkSize )
115
+ ),
116
+ Entropies = collect_entropies (EntropyTasks , []),
117
+ case Entropies of
118
+ {error , _Reason } ->
119
+ flush_entropy_messages ();
120
+ _ ->
121
+ ok
122
+ end ,
123
+ Entropies .
124
+
125
+ collect_entropies ([], Acc ) ->
126
+ lists :reverse (Acc );
127
+ collect_entropies ([Ref | Rest ], Acc ) ->
128
+ receive
129
+ {entropy_generated , Ref , {error , Reason }} ->
130
+ ? LOG_ERROR ([{event , failed_to_generate_replica_2_9_entropy }, {error , Reason }]),
131
+ {error , Reason };
132
+ {entropy_generated , Ref , Entropy } ->
133
+ collect_entropies (Rest , [Entropy | Acc ])
134
+ after 60000 ->
135
+ ? LOG_ERROR ([{event , entropy_generation_timeout }, {ref , Ref }]),
136
+ {error , timeout }
137
+ end .
138
+
139
+ flush_entropy_messages () ->
140
+ ? LOG_INFO ([{event , flush_entropy_messages }]),
141
+ receive
142
+ {entropy_generated , _ , _ } ->
143
+ flush_entropy_messages ()
144
+ after 0 ->
145
+ ok
146
+ end .
106
147
107
148
generate_entropy_keys (_RewardAddr , _Offset , SubChunkStart )
108
149
when SubChunkStart == ? DATA_CHUNK_SIZE ->
@@ -179,20 +220,10 @@ store_entropy(Entropies,
179
220
StoreID2 ,
180
221
RewardAddr ),
181
222
182
- EndTime = erlang :monotonic_time (),
183
- ElapsedTime =
184
- erlang :convert_time_unit (EndTime - StartTime ,
185
- native ,
186
- microsecond ),
187
- % % bytes per second
188
- WriteRate =
189
- case ElapsedTime > 0 of
190
- true -> 1000000 * byte_size (ChunkEntropy ) div ElapsedTime ;
191
- false -> 0
192
- end ,
193
- prometheus_gauge :set (replica_2_9_entropy_store_rate ,
194
- [StoreID2 ],
195
- WriteRate ),
223
+ ar_metrics :record_rate_metric (StartTime ,
224
+ byte_size (ChunkEntropy ),
225
+ replica_2_9_entropy_write_rate ,
226
+ [StoreID2 ]),
196
227
From ! {store_entropy_sub_chunk_written , WaitNAcc + 1 }
197
228
end ),
198
229
WaitNAcc + 1
@@ -240,34 +271,33 @@ record_chunk(PaddedEndOffset, Chunk, RewardAddr, StoreID, FileIndex, IsPrepared)
240
271
true ->
241
272
ar_chunk_storage :get (StartOffset , StartOffset , StoreID )
242
273
end ,
243
- case ReadEntropy of
274
+ RecordChunk = case ReadEntropy of
244
275
{error , _ } = Error2 ->
245
- release_semaphore (Filepath ),
246
276
Error2 ;
247
277
not_found ->
248
- release_semaphore (Filepath ),
249
278
{error , not_prepared_yet2 };
250
279
missing_entropy ->
251
280
Packing = {replica_2_9 , RewardAddr },
252
281
Entropy = generate_missing_entropy (PaddedEndOffset , RewardAddr ),
253
- PackedChunk = ar_packing_server :encipher_replica_2_9_chunk (Chunk , Entropy ),
254
- Result = ar_chunk_storage :record_chunk (
255
- PaddedEndOffset , PackedChunk , Packing , StoreID , FileIndex ),
256
- release_semaphore (Filepath ),
257
- Result ;
282
+ case Entropy of
283
+ {error , Reason } ->
284
+ {error , Reason };
285
+ _ ->
286
+ PackedChunk = ar_packing_server :encipher_replica_2_9_chunk (Chunk , Entropy ),
287
+ ar_chunk_storage :record_chunk (
288
+ PaddedEndOffset , PackedChunk , Packing , StoreID , FileIndex )
289
+ end ;
258
290
no_entropy_yet ->
259
- Result = ar_chunk_storage :record_chunk (
260
- PaddedEndOffset , Chunk , unpacked_padded , StoreID , FileIndex ),
261
- release_semaphore (Filepath ),
262
- Result ;
291
+ ar_chunk_storage :record_chunk (
292
+ PaddedEndOffset , Chunk , unpacked_padded , StoreID , FileIndex );
263
293
{_EndOffset , Entropy } ->
264
294
Packing = {replica_2_9 , RewardAddr },
265
295
PackedChunk = ar_packing_server :encipher_replica_2_9_chunk (Chunk , Entropy ),
266
- Result = ar_chunk_storage :record_chunk (
267
- PaddedEndOffset , PackedChunk , Packing , StoreID , FileIndex ),
268
- release_semaphore ( Filepath ) ,
269
- Result
270
- end .
296
+ ar_chunk_storage :record_chunk (
297
+ PaddedEndOffset , PackedChunk , Packing , StoreID , FileIndex )
298
+ end ,
299
+ release_semaphore ( Filepath ),
300
+ RecordChunk .
271
301
272
302
% % @doc Return the byte (>= ChunkStartOffset, < ChunkEndOffset)
273
303
% % that necessarily belongs to the chunk stored
@@ -316,6 +346,7 @@ record_entropy(ChunkEntropy, BucketEndOffset, StoreID, RewardAddr) ->
316
346
{error , _ } = Error ->
317
347
Error ;
318
348
{_ , UnpackedChunk } ->
349
+ ar_sync_record :delete (EndOffset , EndOffset - ? DATA_CHUNK_SIZE , ar_data_sync , StoreID ),
319
350
ar_packing_server :encipher_replica_2_9_chunk (UnpackedChunk , ChunkEntropy )
320
351
end ;
321
352
false ->
@@ -328,12 +359,6 @@ record_entropy(ChunkEntropy, BucketEndOffset, StoreID, RewardAddr) ->
328
359
{error , _ } = Error2 ->
329
360
Error2 ;
330
361
_ ->
331
- case IsUnpackedChunkRecorded of
332
- true ->
333
- ar_sync_record :delete (EndOffset , EndOffset - ? DATA_CHUNK_SIZE , ar_data_sync , StoreID );
334
- false ->
335
- ok
336
- end ,
337
362
case ar_chunk_storage :write_chunk (EndOffset , Chunk , #{}, StoreID ) of
338
363
{ok , Filepath } ->
339
364
ets :insert (chunk_storage_file_index ,
@@ -347,8 +372,9 @@ record_entropy(ChunkEntropy, BucketEndOffset, StoreID, RewardAddr) ->
347
372
348
373
case Result of
349
374
{error , Reason } ->
350
- ? LOG_ERROR ([{event , failed_to_store_replica_2_9_sub_chunk_entropy },
375
+ ? LOG_ERROR ([{event , failed_to_store_replica_2_9_chunk_entropy },
351
376
{filepath , Filepath },
377
+ {byte , Byte },
352
378
{padded_end_offset , EndOffset },
353
379
{bucket_end_offset , BucketEndOffset },
354
380
{store_id , StoreID },
@@ -423,7 +449,8 @@ shift_entropy_offset(Offset, SectorCount) ->
423
449
acquire_semaphore (Filepath ) ->
424
450
case ets :insert_new (ar_entropy_storage , {{semaphore , Filepath }}) of
425
451
false ->
426
- ? LOG_DEBUG ([{event , details_store_chunk }, {section , waiting_on_semaphore }, {filepath , Filepath }]),
452
+ ? LOG_DEBUG ([
453
+ {event , details_store_chunk }, {section , waiting_on_semaphore }, {filepath , Filepath }]),
427
454
timer :sleep (20 ),
428
455
acquire_semaphore (Filepath );
429
456
true ->
0 commit comments