浏览代码

Add loaded-accounts-data-size field to sim result (#6023)

* Add loaded-accounts-data-size field to sim result

* increase loaded_accounts_data_size visibility to public

* update svm examples

* update rpc tests with additional field
Tao Zhu 5 月之前
父节点
当前提交
49c0d5a706

+ 1 - 0
banks-interface/src/lib.rs

@@ -38,6 +38,7 @@ pub struct TransactionStatus {
 pub struct TransactionSimulationDetails {
     pub logs: Vec<String>,
     pub units_consumed: u64,
+    pub loaded_accounts_data_size: u32,
     pub return_data: Option<TransactionReturnData>,
     pub inner_instructions: Option<Vec<InnerInstructions>>,
 }

+ 2 - 0
banks-server/src/banks_server.rs

@@ -188,6 +188,7 @@ fn simulate_transaction(
         logs,
         post_simulation_accounts: _,
         units_consumed,
+        loaded_accounts_data_size,
         return_data,
         inner_instructions,
     } = bank.simulate_transaction_unchecked(&sanitized_transaction, true);
@@ -195,6 +196,7 @@ fn simulate_transaction(
     let simulation_details = TransactionSimulationDetails {
         logs,
         units_consumed,
+        loaded_accounts_data_size,
         return_data,
         inner_instructions,
     };

+ 1 - 0
rpc-client-api/src/client_error.rs

@@ -8,6 +8,7 @@ use {
 };
 
 #[derive(ThisError, Debug)]
+#[allow(clippy::large_enum_variant)]
 pub enum ErrorKind {
     #[error(transparent)]
     Io(#[from] io::Error),

+ 1 - 0
rpc-client-types/src/response.rs

@@ -401,6 +401,7 @@ pub struct RpcSimulateTransactionResult {
     pub logs: Option<Vec<String>>,
     pub accounts: Option<Vec<Option<UiAccount>>>,
     pub units_consumed: Option<u64>,
+    pub loaded_accounts_data_size: Option<u32>,
     pub return_data: Option<UiTransactionReturnData>,
     pub inner_instructions: Option<Vec<UiInnerInstructions>>,
     pub replacement_blockhash: Option<RpcBlockhash>,

+ 1 - 0
rpc-client/src/mock_sender.rs

@@ -352,6 +352,7 @@ impl RpcSender for MockSender {
                     logs: None,
                     accounts: None,
                     units_consumed: None,
+                    loaded_accounts_data_size: None,
                     return_data: None,
                     inner_instructions: None,
                     replacement_blockhash: None

+ 42 - 1
rpc/src/rpc.rs

@@ -3904,6 +3904,7 @@ pub mod rpc_full {
                     logs,
                     post_simulation_accounts: _,
                     units_consumed,
+                    loaded_accounts_data_size,
                     return_data,
                     inner_instructions: _, // Always `None` due to `enable_cpi_recording = false`
                 } = preflight_bank.simulate_transaction(&transaction, false)
@@ -3923,6 +3924,7 @@ pub mod rpc_full {
                             logs: Some(logs),
                             accounts: None,
                             units_consumed: Some(units_consumed),
+                            loaded_accounts_data_size: Some(loaded_accounts_data_size),
                             return_data: return_data.map(|return_data| return_data.into()),
                             inner_instructions: None,
                             replacement_blockhash: None,
@@ -4002,6 +4004,7 @@ pub mod rpc_full {
                 logs,
                 post_simulation_accounts,
                 units_consumed,
+                loaded_accounts_data_size,
                 return_data,
                 inner_instructions,
             } = bank.simulate_transaction(&transaction, enable_cpi_recording);
@@ -4068,6 +4071,7 @@ pub mod rpc_full {
                     logs: Some(logs),
                     accounts,
                     units_consumed: Some(units_consumed),
+                    loaded_accounts_data_size: Some(loaded_accounts_data_size),
                     return_data: return_data.map(|return_data| return_data.into()),
                     inner_instructions,
                     replacement_blockhash: blockhash,
@@ -5978,6 +5982,12 @@ pub mod tests {
         // Simulation bank must be frozen
         bank.freeze();
 
+        let loaded_account_data_size = bank
+            .get_account(&system_program::id())
+            .unwrap()
+            .data()
+            .len() as u32;
+
         // Good signature with sigVerify=true
         let req = format!(
             r#"{{"jsonrpc":"2.0",
@@ -6017,6 +6027,7 @@ pub mod tests {
                     ],
                     "err":null,
                     "innerInstructions": null,
+                    "loadedAccountsDataSize": loaded_account_data_size,
                     "logs":[
                         "Program 11111111111111111111111111111111 invoke [1]",
                         "Program 11111111111111111111111111111111 success"
@@ -6103,6 +6114,7 @@ pub mod tests {
                     "accounts":null,
                     "err":null,
                     "innerInstructions":null,
+                    "loadedAccountsDataSize": loaded_account_data_size,
                     "logs":[
                         "Program 11111111111111111111111111111111 invoke [1]",
                         "Program 11111111111111111111111111111111 success"
@@ -6133,6 +6145,7 @@ pub mod tests {
                     "accounts":null,
                     "err":null,
                     "innerInstructions":null,
+                    "loadedAccountsDataSize": loaded_account_data_size,
                     "logs":[
                         "Program 11111111111111111111111111111111 invoke [1]",
                         "Program 11111111111111111111111111111111 success"
@@ -6187,6 +6200,7 @@ pub mod tests {
                     "err":"BlockhashNotFound",
                     "accounts":null,
                     "innerInstructions":null,
+                    "loadedAccountsDataSize":0,
                     "logs":[],
                     "replacementBlockhash": null,
                     "returnData": null,
@@ -6220,6 +6234,7 @@ pub mod tests {
                     "accounts":null,
                     "err":null,
                     "innerInstructions":null,
+                    "loadedAccountsDataSize": loaded_account_data_size,
                     "logs":[
                         "Program 11111111111111111111111111111111 invoke [1]",
                         "Program 11111111111111111111111111111111 success"
@@ -6312,6 +6327,17 @@ pub mod tests {
         // Simulation bank must be frozen
         bank.freeze();
 
+        let loaded_accounts_data_size = bank
+            .get_account(&token_account_pubkey)
+            .unwrap()
+            .data()
+            .len() as u32
+            + bank
+                .get_account(&system_program::id())
+                .unwrap()
+                .data()
+                .len() as u32;
+
         let req = format!(
             r#"{{"jsonrpc":"2.0",
                  "id":1,
@@ -6368,6 +6394,7 @@ pub mod tests {
                     ],
                     "err": null,
                     "innerInstructions": null,
+                    "loadedAccountsDataSize": loaded_accounts_data_size,
                     "logs":[
                         "Program 11111111111111111111111111111111 invoke [1]",
                         "Program 11111111111111111111111111111111 success"
@@ -6424,6 +6451,17 @@ pub mod tests {
         // Simulation bank must be frozen
         bank.freeze();
 
+        let loaded_accounts_data_size = bank
+            .get_account(&TestBuiltinEntrypoint::PROGRAM_ID)
+            .unwrap()
+            .data()
+            .len() as u32
+            + bank
+                .get_account(&system_program::id())
+                .unwrap()
+                .data()
+                .len() as u32;
+
         // `innerInstructions` not provided, should not be in response
         let req = format!(
             r#"{{"jsonrpc":"2.0",
@@ -6445,6 +6483,7 @@ pub mod tests {
                     "accounts": null,
                     "err":null,
                     "innerInstructions": null,
+                    "loadedAccountsDataSize": loaded_accounts_data_size,
                     "logs":[
                         "Program TestProgram11111111111111111111111111111111 invoke [1]",
                         "I am logging from a builtin program!",
@@ -6488,6 +6527,7 @@ pub mod tests {
                     "accounts": null,
                     "err":null,
                     "innerInstructions": null,
+                    "loadedAccountsDataSize": loaded_accounts_data_size,
                     "logs":[
                         "Program TestProgram11111111111111111111111111111111 invoke [1]",
                         "I am logging from a builtin program!",
@@ -6552,6 +6592,7 @@ pub mod tests {
                         ]
                         }
                     ],
+                    "loadedAccountsDataSize": loaded_accounts_data_size,
                     "logs":[
                         "Program TestProgram11111111111111111111111111111111 invoke [1]",
                         "I am logging from a builtin program!",
@@ -6813,7 +6854,7 @@ pub mod tests {
         assert_eq!(
             res,
             Some(
-                r#"{"jsonrpc":"2.0","error":{"code":-32002,"message":"Transaction simulation failed: Blockhash not found","data":{"accounts":null,"err":"BlockhashNotFound","innerInstructions":null,"logs":[],"replacementBlockhash":null,"returnData":null,"unitsConsumed":0}},"id":1}"#.to_string(),
+                r#"{"jsonrpc":"2.0","error":{"code":-32002,"message":"Transaction simulation failed: Blockhash not found","data":{"accounts":null,"err":"BlockhashNotFound","innerInstructions":null,"loadedAccountsDataSize":0,"logs":[],"replacementBlockhash":null,"returnData":null,"unitsConsumed":0}},"id":1}"#.to_string(),
             )
         );
 

+ 14 - 4
runtime/src/bank.rs

@@ -335,6 +335,7 @@ pub struct TransactionSimulationResult {
     pub logs: TransactionLogMessages,
     pub post_simulation_accounts: Vec<TransactionAccount>,
     pub units_consumed: u64,
+    pub loaded_accounts_data_size: u32,
     pub return_data: Option<TransactionReturnData>,
     pub inner_instructions: Option<Vec<InnerInstructions>>,
 }
@@ -3337,6 +3338,7 @@ impl Bank {
             return_data,
             inner_instructions,
             units_consumed,
+            loaded_accounts_data_size,
         ) = match processing_result {
             Ok(processed_tx) => match processed_tx {
                 ProcessedTransaction::Executed(executed_tx) => {
@@ -3354,13 +3356,20 @@ impl Bank {
                         details.return_data,
                         details.inner_instructions,
                         details.executed_units,
+                        executed_tx.loaded_transaction.loaded_accounts_data_size,
                     )
                 }
-                ProcessedTransaction::FeesOnly(fees_only_tx) => {
-                    (vec![], Err(fees_only_tx.load_error), None, None, None, 0)
-                }
+                ProcessedTransaction::FeesOnly(fees_only_tx) => (
+                    vec![],
+                    Err(fees_only_tx.load_error),
+                    None,
+                    None,
+                    None,
+                    0,
+                    fees_only_tx.rollback_accounts.data_size() as u32,
+                ),
             },
-            Err(error) => (vec![], Err(error), None, None, None, 0),
+            Err(error) => (vec![], Err(error), None, None, None, 0, 0),
         };
         let logs = logs.unwrap_or_default();
 
@@ -3369,6 +3378,7 @@ impl Bank {
             logs,
             post_simulation_accounts,
             units_consumed,
+            loaded_accounts_data_size,
             return_data,
             inner_instructions,
         }

+ 7 - 0
runtime/src/bank/tests.rs

@@ -13098,6 +13098,8 @@ fn test_failed_simulation_compute_units() {
     const TEST_UNITS: u64 = 10_000;
     const MOCK_BUILTIN_UNITS: u64 = 1;
     let expected_consumed_units = TEST_UNITS + MOCK_BUILTIN_UNITS;
+    let expected_loaded_program_account_data_size =
+        bank.get_account(&program_id).unwrap().data().len() as u32;
     declare_process_instruction!(MockBuiltin, MOCK_BUILTIN_UNITS, |invoke_context| {
         invoke_context.consume_checked(TEST_UNITS).unwrap();
         Err(InstructionError::InvalidInstructionData)
@@ -13113,6 +13115,10 @@ fn test_failed_simulation_compute_units() {
     let sanitized = RuntimeTransaction::from_transaction_for_tests(transaction);
     let simulation = bank.simulate_transaction(&sanitized, false);
     assert_eq!(expected_consumed_units, simulation.units_consumed);
+    assert_eq!(
+        expected_loaded_program_account_data_size,
+        simulation.loaded_accounts_data_size
+    );
 }
 
 /// Test that simulations report the load error of fees-only transactions
@@ -13142,6 +13148,7 @@ fn test_failed_simulation_load_error() {
             logs: vec![],
             post_simulation_accounts: vec![],
             units_consumed: 0,
+            loaded_accounts_data_size: 0,
             return_data: None,
             inner_instructions: None,
         }

+ 5 - 0
svm/examples/json-rpc/server/src/rpc_process.rs

@@ -126,6 +126,7 @@ struct TransactionSimulationResult {
     pub logs: TransactionLogMessages,
     pub post_simulation_accounts: Vec<TransactionAccount>,
     pub units_consumed: u64,
+    pub loaded_accounts_data_size: u32,
     pub return_data: Option<TransactionReturnData>,
     pub inner_instructions: Option<Vec<InnerInstructions>>,
 }
@@ -371,12 +372,14 @@ impl JsonRpcRequestProcessor {
             };
         let logs = logs.unwrap_or_default();
         let units_consumed: u64 = 0;
+        let loaded_accounts_data_size: u32 = 0;
 
         TransactionSimulationResult {
             result: flattened_result,
             logs,
             post_simulation_accounts,
             units_consumed,
+            loaded_accounts_data_size,
             return_data,
             inner_instructions,
         }
@@ -692,6 +695,7 @@ pub mod rpc {
                 logs,
                 post_simulation_accounts,
                 units_consumed,
+                loaded_accounts_data_size,
                 return_data,
                 inner_instructions,
             } = meta.simulate_transaction_unchecked(&transaction, enable_cpi_recording);
@@ -757,6 +761,7 @@ pub mod rpc {
                     logs: Some(logs),
                     accounts,
                     units_consumed: Some(units_consumed),
+                    loaded_accounts_data_size: Some(loaded_accounts_data_size),
                     return_data: return_data.map(|return_data| return_data.into()),
                     inner_instructions,
                     replacement_blockhash: None,

+ 2 - 6
svm/src/account_loader.rs

@@ -123,11 +123,7 @@ pub(crate) struct LoadedTransactionAccount {
 #[cfg_attr(feature = "dev-context-only-utils", derive(Default))]
 #[cfg_attr(
     feature = "dev-context-only-utils",
-    field_qualifiers(
-        program_indices(pub),
-        loaded_accounts_data_size(pub),
-        compute_budget(pub)
-    )
+    field_qualifiers(program_indices(pub), compute_budget(pub))
 )]
 pub struct LoadedTransaction {
     pub accounts: Vec<TransactionAccount>,
@@ -137,7 +133,7 @@ pub struct LoadedTransaction {
     pub(crate) compute_budget: SVMTransactionExecutionBudget,
     pub rent: TransactionRent,
     pub rent_debits: RentDebits,
-    pub(crate) loaded_accounts_data_size: u32,
+    pub loaded_accounts_data_size: u32,
 }
 
 #[derive(PartialEq, Eq, Debug, Clone)]