@@ -2253,4 +2253,316 @@ mod tests {
2253
2253
vec![ ( Err ( TransactionError :: InvalidWritableAccount ) , None ) ]
2254
2254
) ;
2255
2255
}
2256
+
2257
+ #[ test]
2258
+ fn test_load_transaction_accounts_filter_executable_program_account ( ) {
2259
+ let mut mock_bank = TestCallbacks :: default ( ) ;
2260
+ let key1 = Pubkey :: new_unique ( ) ;
2261
+ let owner1 = Pubkey :: new_unique ( ) ;
2262
+
2263
+ let mut data = AccountSharedData :: default ( ) ;
2264
+ data. set_owner ( owner1) ;
2265
+ data. set_lamports ( 93 ) ;
2266
+ mock_bank. accounts_map . insert ( key1, data) ;
2267
+
2268
+ let message = Message {
2269
+ account_keys : vec ! [ key1] ,
2270
+ header : MessageHeader :: default ( ) ,
2271
+ instructions : vec ! [ CompiledInstruction {
2272
+ program_id_index: 0 ,
2273
+ accounts: vec![ ] ,
2274
+ data: vec![ ] ,
2275
+ } ] ,
2276
+ recent_blockhash : Hash :: default ( ) ,
2277
+ } ;
2278
+
2279
+ let sanitized_message = new_unchecked_sanitized_message ( message) ;
2280
+
2281
+ let sanitized_transaction_1 = SanitizedTransaction :: new_for_tests (
2282
+ sanitized_message,
2283
+ vec ! [ Signature :: new_unique( ) ] ,
2284
+ false ,
2285
+ ) ;
2286
+
2287
+ let key2 = Pubkey :: new_unique ( ) ;
2288
+ let owner2 = Pubkey :: new_unique ( ) ;
2289
+
2290
+ let mut account_data = AccountSharedData :: default ( ) ;
2291
+ account_data. set_owner ( owner2) ;
2292
+ account_data. set_lamports ( 90 ) ;
2293
+ mock_bank. accounts_map . insert ( key2, account_data) ;
2294
+
2295
+ let message = Message {
2296
+ account_keys : vec ! [ key1, key2] ,
2297
+ header : MessageHeader :: default ( ) ,
2298
+ instructions : vec ! [ CompiledInstruction {
2299
+ program_id_index: 0 ,
2300
+ accounts: vec![ ] ,
2301
+ data: vec![ ] ,
2302
+ } ] ,
2303
+ recent_blockhash : Hash :: default ( ) ,
2304
+ } ;
2305
+
2306
+ let sanitized_message = new_unchecked_sanitized_message ( message) ;
2307
+
2308
+ let sanitized_transaction_2 = SanitizedTransaction :: new_for_tests (
2309
+ sanitized_message,
2310
+ vec ! [ Signature :: new_unique( ) ] ,
2311
+ false ,
2312
+ ) ;
2313
+
2314
+ let transactions = vec ! [
2315
+ sanitized_transaction_1. clone( ) ,
2316
+ sanitized_transaction_2. clone( ) ,
2317
+ sanitized_transaction_2,
2318
+ sanitized_transaction_1,
2319
+ ] ;
2320
+ let mut check_results = vec ! [
2321
+ ( Ok ( ( ) ) , None , Some ( 25 ) ) ,
2322
+ ( Ok ( ( ) ) , None , Some ( 25 ) ) ,
2323
+ ( Ok ( ( ) ) , None , None ) ,
2324
+ ( Err ( TransactionError :: ProgramAccountNotFound ) , None , None ) ,
2325
+ ] ;
2326
+ let owners = vec ! [ owner1, owner2] ;
2327
+
2328
+ let mut program_accounts = HashMap :: default ( ) ;
2329
+ let mut error_counter = TransactionErrorMetrics :: default ( ) ;
2330
+
2331
+ let _results = load_accounts (
2332
+ & mock_bank,
2333
+ & transactions,
2334
+ & mut check_results,
2335
+ & mut error_counter,
2336
+ & FeeStructure :: default ( ) ,
2337
+ None ,
2338
+ & owners,
2339
+ & mut program_accounts,
2340
+ ) ;
2341
+
2342
+ assert_eq ! (
2343
+ check_results[ 2 ] ,
2344
+ ( Err ( TransactionError :: BlockhashNotFound ) , None , None )
2345
+ ) ;
2346
+ assert_eq ! ( program_accounts. len( ) , 2 ) ;
2347
+ assert_eq ! ( program_accounts[ & key1] , 2 ) ;
2348
+ assert_eq ! ( program_accounts[ & key2] , 1 ) ;
2349
+ }
2350
+
2351
+ #[ test]
2352
+ fn test_load_transaction_accounts_filter_executable_program_account_no_errors ( ) {
2353
+ let mut mock_bank = TestCallbacks :: default ( ) ;
2354
+
2355
+ let keypair1 = Keypair :: new ( ) ;
2356
+ let keypair2 = Keypair :: new ( ) ;
2357
+
2358
+ let non_program_pubkey1 = Pubkey :: new_unique ( ) ;
2359
+ let non_program_pubkey2 = Pubkey :: new_unique ( ) ;
2360
+ let program1_pubkey = Pubkey :: new_unique ( ) ;
2361
+ let program2_pubkey = Pubkey :: new_unique ( ) ;
2362
+ let account1_pubkey = Pubkey :: new_unique ( ) ;
2363
+ let account2_pubkey = Pubkey :: new_unique ( ) ;
2364
+ let account3_pubkey = Pubkey :: new_unique ( ) ;
2365
+ let account4_pubkey = Pubkey :: new_unique ( ) ;
2366
+ let account5_pubkey = Pubkey :: new_unique ( ) ;
2367
+
2368
+ let mut fee_payer_account_data = AccountSharedData :: default ( ) ;
2369
+ fee_payer_account_data. set_lamports ( 200 ) ;
2370
+ mock_bank
2371
+ . accounts_map
2372
+ . insert ( keypair1. pubkey ( ) , fee_payer_account_data. clone ( ) ) ;
2373
+
2374
+ mock_bank
2375
+ . accounts_map
2376
+ . insert ( keypair2. pubkey ( ) , fee_payer_account_data. clone ( ) ) ;
2377
+
2378
+ mock_bank. accounts_map . insert (
2379
+ non_program_pubkey1,
2380
+ AccountSharedData :: new ( 1 , 10 , & account5_pubkey) ,
2381
+ ) ;
2382
+ mock_bank. accounts_map . insert (
2383
+ non_program_pubkey2,
2384
+ AccountSharedData :: new ( 1 , 10 , & account5_pubkey) ,
2385
+ ) ;
2386
+ mock_bank. accounts_map . insert (
2387
+ program1_pubkey,
2388
+ AccountSharedData :: new ( 40 , 1 , & account5_pubkey) ,
2389
+ ) ;
2390
+ mock_bank. accounts_map . insert (
2391
+ program2_pubkey,
2392
+ AccountSharedData :: new ( 40 , 1 , & account5_pubkey) ,
2393
+ ) ;
2394
+ mock_bank. accounts_map . insert (
2395
+ account1_pubkey,
2396
+ AccountSharedData :: new ( 1 , 10 , & non_program_pubkey1) ,
2397
+ ) ;
2398
+ mock_bank. accounts_map . insert (
2399
+ account2_pubkey,
2400
+ AccountSharedData :: new ( 1 , 10 , & non_program_pubkey2) ,
2401
+ ) ;
2402
+ mock_bank. accounts_map . insert (
2403
+ account3_pubkey,
2404
+ AccountSharedData :: new ( 40 , 1 , & program1_pubkey) ,
2405
+ ) ;
2406
+ mock_bank. accounts_map . insert (
2407
+ account4_pubkey,
2408
+ AccountSharedData :: new ( 40 , 1 , & program2_pubkey) ,
2409
+ ) ;
2410
+
2411
+ let tx1 = Transaction :: new_with_compiled_instructions (
2412
+ & [ & keypair1] ,
2413
+ & [ non_program_pubkey1] ,
2414
+ Hash :: new_unique ( ) ,
2415
+ vec ! [ account1_pubkey, account2_pubkey, account3_pubkey] ,
2416
+ vec ! [ CompiledInstruction :: new( 1 , & ( ) , vec![ 0 ] ) ] ,
2417
+ ) ;
2418
+ let sanitized_tx1 = SanitizedTransaction :: from_transaction_for_tests ( tx1) ;
2419
+
2420
+ let tx2 = Transaction :: new_with_compiled_instructions (
2421
+ & [ & keypair2] ,
2422
+ & [ non_program_pubkey2] ,
2423
+ Hash :: new_unique ( ) ,
2424
+ vec ! [ account4_pubkey, account3_pubkey, account2_pubkey] ,
2425
+ vec ! [ CompiledInstruction :: new( 1 , & ( ) , vec![ 0 ] ) ] ,
2426
+ ) ;
2427
+ let sanitized_tx2 = SanitizedTransaction :: from_transaction_for_tests ( tx2) ;
2428
+
2429
+ let owners = & [ program1_pubkey, program2_pubkey] ;
2430
+
2431
+ let mut program_accounts = HashMap :: default ( ) ;
2432
+ let mut error_counter = TransactionErrorMetrics :: default ( ) ;
2433
+
2434
+ let _results = load_accounts (
2435
+ & mock_bank,
2436
+ & [ sanitized_tx1, sanitized_tx2] ,
2437
+ & mut [ ( Ok ( ( ) ) , None , Some ( 0 ) ) , ( Ok ( ( ) ) , None , Some ( 0 ) ) ] ,
2438
+ & mut error_counter,
2439
+ & FeeStructure :: default ( ) ,
2440
+ None ,
2441
+ owners,
2442
+ & mut program_accounts,
2443
+ ) ;
2444
+
2445
+ // The result should contain only account3_pubkey, and account4_pubkey as the program accounts
2446
+ assert_eq ! ( program_accounts. len( ) , 2 ) ;
2447
+ assert_eq ! (
2448
+ program_accounts
2449
+ . get( & account3_pubkey)
2450
+ . expect( "failed to find the program account" ) ,
2451
+ & 2
2452
+ ) ;
2453
+ assert_eq ! (
2454
+ program_accounts
2455
+ . get( & account4_pubkey)
2456
+ . expect( "failed to find the program account" ) ,
2457
+ & 1
2458
+ ) ;
2459
+ }
2460
+
2461
+ #[ test]
2462
+ fn test_load_transaction_accounts_filter_executable_program_account_invalid_blockhash ( ) {
2463
+ let mut mock_bank = TestCallbacks :: default ( ) ;
2464
+
2465
+ let keypair1 = Keypair :: new ( ) ;
2466
+ let keypair2 = Keypair :: new ( ) ;
2467
+
2468
+ let non_program_pubkey1 = Pubkey :: new_unique ( ) ;
2469
+ let non_program_pubkey2 = Pubkey :: new_unique ( ) ;
2470
+ let program1_pubkey = Pubkey :: new_unique ( ) ;
2471
+ let program2_pubkey = Pubkey :: new_unique ( ) ;
2472
+ let account1_pubkey = Pubkey :: new_unique ( ) ;
2473
+ let account2_pubkey = Pubkey :: new_unique ( ) ;
2474
+ let account3_pubkey = Pubkey :: new_unique ( ) ;
2475
+ let account4_pubkey = Pubkey :: new_unique ( ) ;
2476
+ let account5_pubkey = Pubkey :: new_unique ( ) ;
2477
+
2478
+ let mut fee_payer_account_data = AccountSharedData :: default ( ) ;
2479
+ fee_payer_account_data. set_lamports ( 200 ) ;
2480
+ mock_bank
2481
+ . accounts_map
2482
+ . insert ( keypair1. pubkey ( ) , fee_payer_account_data. clone ( ) ) ;
2483
+
2484
+ mock_bank
2485
+ . accounts_map
2486
+ . insert ( keypair2. pubkey ( ) , fee_payer_account_data. clone ( ) ) ;
2487
+
2488
+ mock_bank. accounts_map . insert (
2489
+ non_program_pubkey1,
2490
+ AccountSharedData :: new ( 1 , 10 , & account5_pubkey) ,
2491
+ ) ;
2492
+ mock_bank. accounts_map . insert (
2493
+ non_program_pubkey2,
2494
+ AccountSharedData :: new ( 1 , 10 , & account5_pubkey) ,
2495
+ ) ;
2496
+ mock_bank. accounts_map . insert (
2497
+ program1_pubkey,
2498
+ AccountSharedData :: new ( 40 , 1 , & account5_pubkey) ,
2499
+ ) ;
2500
+ mock_bank. accounts_map . insert (
2501
+ program2_pubkey,
2502
+ AccountSharedData :: new ( 40 , 1 , & account5_pubkey) ,
2503
+ ) ;
2504
+ mock_bank. accounts_map . insert (
2505
+ account1_pubkey,
2506
+ AccountSharedData :: new ( 1 , 10 , & non_program_pubkey1) ,
2507
+ ) ;
2508
+ mock_bank. accounts_map . insert (
2509
+ account2_pubkey,
2510
+ AccountSharedData :: new ( 1 , 10 , & non_program_pubkey2) ,
2511
+ ) ;
2512
+ mock_bank. accounts_map . insert (
2513
+ account3_pubkey,
2514
+ AccountSharedData :: new ( 40 , 1 , & program1_pubkey) ,
2515
+ ) ;
2516
+ mock_bank. accounts_map . insert (
2517
+ account4_pubkey,
2518
+ AccountSharedData :: new ( 40 , 1 , & program2_pubkey) ,
2519
+ ) ;
2520
+
2521
+ let tx1 = Transaction :: new_with_compiled_instructions (
2522
+ & [ & keypair1] ,
2523
+ & [ non_program_pubkey1] ,
2524
+ Hash :: new_unique ( ) ,
2525
+ vec ! [ account1_pubkey, account2_pubkey, account3_pubkey] ,
2526
+ vec ! [ CompiledInstruction :: new( 1 , & ( ) , vec![ 0 ] ) ] ,
2527
+ ) ;
2528
+ let sanitized_tx1 = SanitizedTransaction :: from_transaction_for_tests ( tx1) ;
2529
+
2530
+ let tx2 = Transaction :: new_with_compiled_instructions (
2531
+ & [ & keypair2] ,
2532
+ & [ non_program_pubkey2] ,
2533
+ Hash :: new_unique ( ) ,
2534
+ vec ! [ account4_pubkey, account3_pubkey, account2_pubkey] ,
2535
+ vec ! [ CompiledInstruction :: new( 1 , & ( ) , vec![ 0 ] ) ] ,
2536
+ ) ;
2537
+ // Let's not register blockhash from tx2. This should cause the tx2 to fail
2538
+ let sanitized_tx2 = SanitizedTransaction :: from_transaction_for_tests ( tx2) ;
2539
+
2540
+ let owners = & [ program1_pubkey, program2_pubkey] ;
2541
+
2542
+ let mut program_accounts = HashMap :: default ( ) ;
2543
+ let mut error_counter = TransactionErrorMetrics :: default ( ) ;
2544
+
2545
+ let mut lock_results = vec ! [ ( Ok ( ( ) ) , None , Some ( 0 ) ) , ( Ok ( ( ) ) , None , None ) ] ;
2546
+
2547
+ let _results = load_accounts (
2548
+ & mock_bank,
2549
+ & [ sanitized_tx1, sanitized_tx2] ,
2550
+ & mut lock_results,
2551
+ & mut error_counter,
2552
+ & FeeStructure :: default ( ) ,
2553
+ None ,
2554
+ owners,
2555
+ & mut program_accounts,
2556
+ ) ;
2557
+
2558
+ // The result should contain only account3_pubkey as the program accounts
2559
+ assert_eq ! ( program_accounts. len( ) , 1 ) ;
2560
+ assert_eq ! (
2561
+ program_accounts
2562
+ . get( & account3_pubkey)
2563
+ . expect( "failed to find the program account" ) ,
2564
+ & 1
2565
+ ) ;
2566
+ assert_eq ! ( lock_results[ 1 ] . 0 , Err ( TransactionError :: BlockhashNotFound ) ) ;
2567
+ }
2256
2568
}
0 commit comments