@@ -235,6 +235,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
235
235
236
236
let ( validation_results, validate_fees_time) = measure ! ( self . validate_fees(
237
237
callbacks,
238
+ config. account_overrides,
238
239
sanitized_txs,
239
240
check_results,
240
241
& environment. feature_set,
@@ -380,6 +381,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
380
381
fn validate_fees < CB : TransactionProcessingCallback > (
381
382
& self ,
382
383
callbacks : & CB ,
384
+ account_overrides : Option < & AccountOverrides > ,
383
385
sanitized_txs : & [ impl core:: borrow:: Borrow < SanitizedTransaction > ] ,
384
386
check_results : Vec < TransactionCheckResult > ,
385
387
feature_set : & FeatureSet ,
@@ -395,6 +397,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
395
397
let message = sanitized_tx. borrow ( ) . message ( ) ;
396
398
self . validate_transaction_fee_payer (
397
399
callbacks,
400
+ account_overrides,
398
401
message,
399
402
checked_details,
400
403
feature_set,
@@ -413,6 +416,7 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
413
416
fn validate_transaction_fee_payer < CB : TransactionProcessingCallback > (
414
417
& self ,
415
418
callbacks : & CB ,
419
+ account_overrides : Option < & AccountOverrides > ,
416
420
message : & SanitizedMessage ,
417
421
checked_details : CheckedTransactionDetails ,
418
422
feature_set : & FeatureSet ,
@@ -429,8 +433,12 @@ impl<FG: ForkGraph> TransactionBatchProcessor<FG> {
429
433
} ) ?;
430
434
431
435
let fee_payer_address = message. fee_payer ( ) ;
432
- let Some ( mut fee_payer_account) = callbacks. get_account_shared_data ( fee_payer_address)
433
- else {
436
+
437
+ let fee_payer_account = account_overrides
438
+ . and_then ( |overrides| overrides. get ( fee_payer_address) . cloned ( ) )
439
+ . or_else ( || callbacks. get_account_shared_data ( fee_payer_address) ) ;
440
+
441
+ let Some ( mut fee_payer_account) = fee_payer_account else {
434
442
error_counters. account_not_found += 1 ;
435
443
return Err ( TransactionError :: AccountNotFound ) ;
436
444
} ;
@@ -2001,6 +2009,7 @@ mod tests {
2001
2009
let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2002
2010
let result = batch_processor. validate_transaction_fee_payer (
2003
2011
& mock_bank,
2012
+ None ,
2004
2013
& message,
2005
2014
CheckedTransactionDetails {
2006
2015
nonce : None ,
@@ -2073,6 +2082,7 @@ mod tests {
2073
2082
let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2074
2083
let result = batch_processor. validate_transaction_fee_payer (
2075
2084
& mock_bank,
2085
+ None ,
2076
2086
& message,
2077
2087
CheckedTransactionDetails {
2078
2088
nonce : None ,
@@ -2120,6 +2130,7 @@ mod tests {
2120
2130
let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2121
2131
let result = batch_processor. validate_transaction_fee_payer (
2122
2132
& mock_bank,
2133
+ None ,
2123
2134
& message,
2124
2135
CheckedTransactionDetails {
2125
2136
nonce : None ,
@@ -2152,6 +2163,7 @@ mod tests {
2152
2163
let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2153
2164
let result = batch_processor. validate_transaction_fee_payer (
2154
2165
& mock_bank,
2166
+ None ,
2155
2167
& message,
2156
2168
CheckedTransactionDetails {
2157
2169
nonce : None ,
@@ -2188,6 +2200,7 @@ mod tests {
2188
2200
let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2189
2201
let result = batch_processor. validate_transaction_fee_payer (
2190
2202
& mock_bank,
2203
+ None ,
2191
2204
& message,
2192
2205
CheckedTransactionDetails {
2193
2206
nonce : None ,
@@ -2222,6 +2235,7 @@ mod tests {
2222
2235
let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2223
2236
let result = batch_processor. validate_transaction_fee_payer (
2224
2237
& mock_bank,
2238
+ None ,
2225
2239
& message,
2226
2240
CheckedTransactionDetails {
2227
2241
nonce : None ,
@@ -2253,6 +2267,7 @@ mod tests {
2253
2267
let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2254
2268
let result = batch_processor. validate_transaction_fee_payer (
2255
2269
& mock_bank,
2270
+ None ,
2256
2271
& message,
2257
2272
CheckedTransactionDetails {
2258
2273
nonce : None ,
@@ -2314,6 +2329,7 @@ mod tests {
2314
2329
) ) ;
2315
2330
let result = batch_processor. validate_transaction_fee_payer (
2316
2331
& mock_bank,
2332
+ None ,
2317
2333
& message,
2318
2334
CheckedTransactionDetails {
2319
2335
nonce : nonce. clone ( ) ,
@@ -2371,6 +2387,7 @@ mod tests {
2371
2387
let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2372
2388
let result = batch_processor. validate_transaction_fee_payer (
2373
2389
& mock_bank,
2390
+ None ,
2374
2391
& message,
2375
2392
CheckedTransactionDetails {
2376
2393
nonce : None ,
@@ -2386,4 +2403,58 @@ mod tests {
2386
2403
assert_eq ! ( result, Err ( TransactionError :: InsufficientFundsForFee ) ) ;
2387
2404
}
2388
2405
}
2406
+
2407
+ #[ test]
2408
+ fn test_validate_account_override_usage_on_validate_fee ( ) {
2409
+ /*
2410
+ The test setups an account override with enough lamport to pass validate fee.
2411
+ The account_db has the account with minimum rent amount thus would fail the validate_free.
2412
+ The test verify that the override is used with a passing test of validate fee.
2413
+ */
2414
+ let lamports_per_signature = 5000 ;
2415
+
2416
+ let message =
2417
+ new_unchecked_sanitized_message ( Message :: new ( & [ ] , Some ( & Pubkey :: new_unique ( ) ) ) ) ;
2418
+
2419
+ let fee_payer_address = message. fee_payer ( ) ;
2420
+ let transaction_fee = lamports_per_signature;
2421
+ let rent_collector = RentCollector :: default ( ) ;
2422
+ let min_balance = rent_collector. rent . minimum_balance ( 0 ) ;
2423
+
2424
+ let fee_payer_account = AccountSharedData :: new ( min_balance, 0 , & Pubkey :: default ( ) ) ;
2425
+ let mut mock_accounts = HashMap :: new ( ) ;
2426
+ mock_accounts. insert ( * fee_payer_address, fee_payer_account. clone ( ) ) ;
2427
+
2428
+ let necessary_balance = min_balance + transaction_fee;
2429
+ let mut account_overrides = AccountOverrides :: default ( ) ;
2430
+ let fee_payer_account_override =
2431
+ AccountSharedData :: new ( necessary_balance, 0 , & Pubkey :: default ( ) ) ;
2432
+ account_overrides. set_account ( fee_payer_address, Some ( fee_payer_account_override) ) ;
2433
+
2434
+ let mock_bank = MockBankCallback {
2435
+ account_shared_data : Arc :: new ( RwLock :: new ( mock_accounts) ) ,
2436
+ } ;
2437
+
2438
+ let mut error_counters = TransactionErrorMetrics :: default ( ) ;
2439
+ let batch_processor = TransactionBatchProcessor :: < TestForkGraph > :: default ( ) ;
2440
+
2441
+ let result = batch_processor. validate_transaction_fee_payer (
2442
+ & mock_bank,
2443
+ Some ( & account_overrides) ,
2444
+ & message,
2445
+ CheckedTransactionDetails {
2446
+ nonce : None ,
2447
+ lamports_per_signature,
2448
+ } ,
2449
+ & FeatureSet :: default ( ) ,
2450
+ & FeeStructure :: default ( ) ,
2451
+ & rent_collector,
2452
+ & mut error_counters,
2453
+ ) ;
2454
+ assert ! (
2455
+ result. is_ok( ) ,
2456
+ "test_account_override_used: {:?}" ,
2457
+ result. err( )
2458
+ ) ;
2459
+ }
2389
2460
}
0 commit comments