2
2
3
3
use super :: tools:: get_transaction;
4
4
use crate :: operation_pool:: tests:: POOL_SETTINGS ;
5
+ use crate :: tests:: tools:: create_executesc;
5
6
use crate :: tests:: tools:: { self , get_transaction_with_addresses, pool_test} ;
6
7
use crate :: PoolSettings ;
7
8
use massa_models:: Address ;
@@ -38,7 +39,7 @@ async fn test_pool() {
38
39
cmd @ ProtocolCommand :: PropagateOperations ( _) => Some ( cmd) ,
39
40
_ => None ,
40
41
} ;
41
- // generate transactions
42
+ // generate (id, transactions, range of validity) by threads
42
43
let mut thread_tx_lists = vec ! [ Vec :: new( ) ; * thread_count as usize ] ;
43
44
for i in 0 ..18 {
44
45
let fee = 40 + i;
@@ -89,7 +90,7 @@ async fn test_pool() {
89
90
lst. truncate ( * max_pool_size_per_thread as usize ) ;
90
91
}
91
92
92
- // checks ops for thread 0 and 1 and various periods
93
+ // checks ops are the expected ones for thread 0 and 1 and various periods
93
94
for thread in 0u8 ..=1 {
94
95
for period in 0u64 ..70 {
95
96
let target_slot = Slot :: new ( period, thread) ;
@@ -113,7 +114,8 @@ async fn test_pool() {
113
114
. map( |( id, op, _) | ( id, op. to_bytes_compact( ) . unwrap( ) ) ) ) ) ;
114
115
}
115
116
}
116
- // op ending before or at period 45 should be discarded
117
+ // op ending before or at period 45 won't appear in the block due to incompatible validity range
118
+ // we don't keep them as expected ops
117
119
let final_period = 45u64 ;
118
120
pool_command_sender
119
121
. update_latest_final_periods ( vec ! [ final_period; * thread_count as usize ] )
@@ -122,7 +124,7 @@ async fn test_pool() {
122
124
for lst in thread_tx_lists. iter_mut ( ) {
123
125
lst. retain ( |( _, op, _) | op. content . expire_period > final_period) ;
124
126
}
125
- // checks ops for thread 0 and 1 and various periods
127
+ // checks ops are the expected ones for thread 0 and 1 and various periods
126
128
for thread in 0u8 ..=1 {
127
129
for period in 0u64 ..70 {
128
130
let target_slot = Slot :: new ( period, thread) ;
@@ -146,7 +148,7 @@ async fn test_pool() {
146
148
. map( |( id, op, _) | ( id, op. to_bytes_compact( ) . unwrap( ) ) ) ) ) ;
147
149
}
148
150
}
149
- // add transactions from protocol with a high fee but too much in the future: should be ignored
151
+ // Add transactions that should be ignored despite their high fees, due to them being too far in the future
150
152
{
151
153
pool_command_sender
152
154
. update_current_slot ( Slot :: new ( 10 , 0 ) )
@@ -183,6 +185,173 @@ async fn test_pool() {
183
185
)
184
186
. await ;
185
187
}
188
+
189
+ #[ tokio:: test]
190
+ #[ serial]
191
+ async fn test_pool_with_execute_sc ( ) {
192
+ let ( cfg, thread_count, operation_validity_periods, max_pool_size_per_thread) : & (
193
+ PoolSettings ,
194
+ u8 ,
195
+ u64 ,
196
+ u64 ,
197
+ ) = & POOL_SETTINGS ;
198
+
199
+ pool_test (
200
+ cfg,
201
+ * thread_count,
202
+ * operation_validity_periods,
203
+ async move |mut protocol_controller, mut pool_command_sender, pool_manager| {
204
+ let op_filter = |cmd| match cmd {
205
+ cmd @ ProtocolCommand :: PropagateOperations ( _) => Some ( cmd) ,
206
+ _ => None ,
207
+ } ;
208
+ // generate (id, transactions, range of validity) by threads
209
+ let mut thread_tx_lists = vec ! [ Vec :: new( ) ; * thread_count as usize ] ;
210
+ for i in 0 ..18 {
211
+ let fee = 40 + i;
212
+ let expire_period: u64 = 40 + i;
213
+ let start_period = expire_period. saturating_sub ( * operation_validity_periods) ;
214
+ let ( op, thread) = create_executesc ( expire_period, fee, 100 , 1 ) ; // Only the fee determines the rentability
215
+ let id = op. verify_integrity ( ) . unwrap ( ) ;
216
+
217
+ let mut ops = OperationHashMap :: default ( ) ;
218
+ ops. insert ( id, op. clone ( ) ) ;
219
+
220
+ pool_command_sender
221
+ . add_operations ( ops. clone ( ) )
222
+ . await
223
+ . unwrap ( ) ;
224
+
225
+ let newly_added = match protocol_controller
226
+ . wait_command ( 250 . into ( ) , op_filter)
227
+ . await
228
+ {
229
+ Some ( ProtocolCommand :: PropagateOperations ( ops) ) => ops,
230
+ Some ( _) => panic ! ( "unexpected protocol command" ) ,
231
+ None => panic ! ( "unexpected timeout reached" ) ,
232
+ } ;
233
+ assert_eq ! (
234
+ newly_added. keys( ) . copied( ) . collect:: <Vec <_>>( ) ,
235
+ ops. keys( ) . copied( ) . collect:: <Vec <_>>( )
236
+ ) ;
237
+
238
+ // duplicate
239
+ pool_command_sender
240
+ . add_operations ( ops. clone ( ) )
241
+ . await
242
+ . unwrap ( ) ;
243
+
244
+ if let Some ( cmd) = protocol_controller
245
+ . wait_command ( 250 . into ( ) , op_filter)
246
+ . await
247
+ {
248
+ panic ! ( "unexpected protocol command {:?}" , cmd)
249
+ } ;
250
+
251
+ thread_tx_lists[ thread as usize ] . push ( ( id, op, start_period..=expire_period) ) ;
252
+ }
253
+ // sort from bigger fee to smaller and truncate
254
+ for lst in thread_tx_lists. iter_mut ( ) {
255
+ lst. reverse ( ) ;
256
+ lst. truncate ( * max_pool_size_per_thread as usize ) ;
257
+ }
258
+
259
+ // checks ops are the expected ones for thread 0 and 1 and various periods
260
+ for thread in 0u8 ..=1 {
261
+ for period in 0u64 ..70 {
262
+ let target_slot = Slot :: new ( period, thread) ;
263
+ let max_count = 3 ;
264
+ let res = pool_command_sender
265
+ . get_operation_batch (
266
+ target_slot,
267
+ OperationHashSet :: default ( ) ,
268
+ max_count,
269
+ 10000 ,
270
+ )
271
+ . await
272
+ . unwrap ( ) ;
273
+ assert ! ( res
274
+ . iter( )
275
+ . map( |( id, op, _) | ( id, op. to_bytes_compact( ) . unwrap( ) ) )
276
+ . eq( thread_tx_lists[ target_slot. thread as usize ]
277
+ . iter( )
278
+ . filter( |( _, _, r) | r. contains( & target_slot. period) )
279
+ . take( max_count)
280
+ . map( |( id, op, _) | ( id, op. to_bytes_compact( ) . unwrap( ) ) ) ) ) ;
281
+ }
282
+ }
283
+ // op ending before or at period 45 won't appear in the block due to incompatible validity range
284
+ // we don't keep them as expected ops
285
+ let final_period = 45u64 ;
286
+ pool_command_sender
287
+ . update_latest_final_periods ( vec ! [ final_period; * thread_count as usize ] )
288
+ . await
289
+ . unwrap ( ) ;
290
+ for lst in thread_tx_lists. iter_mut ( ) {
291
+ lst. retain ( |( _, op, _) | op. content . expire_period > final_period) ;
292
+ }
293
+ // checks ops are the expected ones for thread 0 and 1 and various periods
294
+ for thread in 0u8 ..=1 {
295
+ for period in 0u64 ..70 {
296
+ let target_slot = Slot :: new ( period, thread) ;
297
+ let max_count = 4 ;
298
+ let res = pool_command_sender
299
+ . get_operation_batch (
300
+ target_slot,
301
+ OperationHashSet :: default ( ) ,
302
+ max_count,
303
+ 10000 ,
304
+ )
305
+ . await
306
+ . unwrap ( ) ;
307
+ assert ! ( res
308
+ . iter( )
309
+ . map( |( id, op, _) | ( id, op. to_bytes_compact( ) . unwrap( ) ) )
310
+ . eq( thread_tx_lists[ target_slot. thread as usize ]
311
+ . iter( )
312
+ . filter( |( _, _, r) | r. contains( & target_slot. period) )
313
+ . take( max_count)
314
+ . map( |( id, op, _) | ( id, op. to_bytes_compact( ) . unwrap( ) ) ) ) ) ;
315
+ }
316
+ }
317
+ // Add transactions that should be ignored despite their high fees, due to them being too far in the future
318
+ {
319
+ pool_command_sender
320
+ . update_current_slot ( Slot :: new ( 10 , 0 ) )
321
+ . await
322
+ . unwrap ( ) ;
323
+ let fee = 1000 ;
324
+ let expire_period: u64 = 300 ;
325
+ let ( op, thread) = get_transaction ( expire_period, fee) ;
326
+ let id = op. verify_integrity ( ) . unwrap ( ) ;
327
+ let mut ops = OperationHashMap :: default ( ) ;
328
+ ops. insert ( id, op) ;
329
+
330
+ pool_command_sender. add_operations ( ops) . await . unwrap ( ) ;
331
+
332
+ if let Some ( cmd) = protocol_controller
333
+ . wait_command ( 250 . into ( ) , op_filter)
334
+ . await
335
+ {
336
+ panic ! ( "unexpected protocol command {:?}" , cmd)
337
+ } ;
338
+ let res = pool_command_sender
339
+ . get_operation_batch (
340
+ Slot :: new ( expire_period - 1 , thread) ,
341
+ OperationHashSet :: default ( ) ,
342
+ 10 ,
343
+ 10000 ,
344
+ )
345
+ . await
346
+ . unwrap ( ) ;
347
+ assert ! ( res. is_empty( ) ) ;
348
+ }
349
+ ( protocol_controller, pool_command_sender, pool_manager)
350
+ } ,
351
+ )
352
+ . await ;
353
+ }
354
+
186
355
#[ tokio:: test]
187
356
#[ serial]
188
357
async fn test_pool_with_protocol_events ( ) {
@@ -199,7 +368,7 @@ async fn test_pool_with_protocol_events() {
199
368
_ => None ,
200
369
} ;
201
370
202
- // generate transactions
371
+ // generate (id, transactions, range of validity) by threads
203
372
let mut thread_tx_lists = vec ! [ Vec :: new( ) ; * thread_count as usize ] ;
204
373
for i in 0 ..18 {
205
374
let fee = 40 + i;
0 commit comments