Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions banks-interface/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,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>>,
}
Expand Down
2 changes: 2 additions & 0 deletions banks-server/src/banks_server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -183,13 +183,15 @@ fn simulate_transaction(
logs,
post_simulation_accounts: _,
units_consumed,
loaded_accounts_data_size,
return_data,
inner_instructions,
} = bank.simulate_transaction_unchecked(&sanitized_transaction, true);

let simulation_details = TransactionSimulationDetails {
logs,
units_consumed,
loaded_accounts_data_size,
return_data,
inner_instructions,
};
Expand Down
1 change: 1 addition & 0 deletions rpc-client-api/src/client_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use {
};

#[derive(ThisError, Debug)]
#[allow(clippy::large_enum_variant)]
pub enum ErrorKind {
#[error(transparent)]
Io(#[from] io::Error),
Expand Down
1 change: 1 addition & 0 deletions rpc-client-types/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand Down
1 change: 1 addition & 0 deletions rpc-client/src/mock_sender.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,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
Expand Down
43 changes: 42 additions & 1 deletion rpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3900,6 +3900,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)
Expand All @@ -3919,6 +3920,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,
Expand Down Expand Up @@ -3998,6 +4000,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);
Expand Down Expand Up @@ -4064,6 +4067,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,
Expand Down Expand Up @@ -5976,6 +5980,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",
Expand Down Expand Up @@ -6015,6 +6025,7 @@ pub mod tests {
],
"err":null,
"innerInstructions": null,
"loadedAccountsDataSize": loaded_account_data_size,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -6101,6 +6112,7 @@ pub mod tests {
"accounts":null,
"err":null,
"innerInstructions":null,
"loadedAccountsDataSize": loaded_account_data_size,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -6131,6 +6143,7 @@ pub mod tests {
"accounts":null,
"err":null,
"innerInstructions":null,
"loadedAccountsDataSize": loaded_account_data_size,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -6185,6 +6198,7 @@ pub mod tests {
"err":"BlockhashNotFound",
"accounts":null,
"innerInstructions":null,
"loadedAccountsDataSize":0,
"logs":[],
"replacementBlockhash": null,
"returnData": null,
Expand Down Expand Up @@ -6218,6 +6232,7 @@ pub mod tests {
"accounts":null,
"err":null,
"innerInstructions":null,
"loadedAccountsDataSize": loaded_account_data_size,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -6310,6 +6325,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,
Expand Down Expand Up @@ -6366,6 +6392,7 @@ pub mod tests {
],
"err": null,
"innerInstructions": null,
"loadedAccountsDataSize": loaded_accounts_data_size,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -6422,6 +6449,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",
Expand All @@ -6443,6 +6481,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!",
Expand Down Expand Up @@ -6486,6 +6525,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!",
Expand Down Expand Up @@ -6550,6 +6590,7 @@ pub mod tests {
]
}
],
"loadedAccountsDataSize": loaded_accounts_data_size,
"logs":[
"Program TestProgram11111111111111111111111111111111 invoke [1]",
"I am logging from a builtin program!",
Expand Down Expand Up @@ -6811,7 +6852,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(),
)
);

Expand Down
18 changes: 14 additions & 4 deletions runtime/src/bank.rs
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,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>>,
}
Expand Down Expand Up @@ -3311,6 +3312,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) => {
Expand All @@ -3328,13 +3330,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();

Expand All @@ -3343,6 +3352,7 @@ impl Bank {
logs,
post_simulation_accounts,
units_consumed,
loaded_accounts_data_size,
return_data,
inner_instructions,
}
Expand Down
7 changes: 7 additions & 0 deletions runtime/src/bank/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13167,6 +13167,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)
Expand All @@ -13182,6 +13184,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
Expand Down Expand Up @@ -13211,6 +13217,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,
}
Expand Down
5 changes: 5 additions & 0 deletions svm/examples/json-rpc/server/src/rpc_process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,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>>,
}
Expand Down Expand Up @@ -365,12 +366,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,
}
Expand Down Expand Up @@ -686,6 +689,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);
Expand Down Expand Up @@ -751,6 +755,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,
Expand Down
8 changes: 2 additions & 6 deletions svm/src/account_loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>,
Expand All @@ -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)]
Expand Down
Loading