Skip to content

Commit

Permalink
rpc: return inner instructions from simulate tx
Browse files Browse the repository at this point in the history
  • Loading branch information
buffalojoec committed Dec 6, 2023
1 parent deb56c1 commit 4d25e6a
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
1 change: 1 addition & 0 deletions docs/src/api/methods/_simulateTransaction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ The result will be an RpcResponse JSON object with `value` set to a JSON object
- `returnData: <object|null>` - the most-recent return data generated by an instruction in the transaction, with the following fields:
- `programId: <string>` - the program that generated the return data, as base-58 encoded Pubkey
- `data: <[string, encoding]>` - the return data itself, as base-64 encoded binary data
- `innerInstructions: <array|null>` - List of [inner instructions](#inner-instructions-structure) or `null` if inner instruction recording was not requested in this simulation

</CodeParams>

Expand Down
5 changes: 3 additions & 2 deletions rpc-client-api/src/response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@ use {
transaction::{Result, TransactionError},
},
solana_transaction_status::{
ConfirmedTransactionStatusWithSignature, TransactionConfirmationStatus, UiConfirmedBlock,
UiTransactionReturnData,
ConfirmedTransactionStatusWithSignature, InnerInstructions, TransactionConfirmationStatus,
UiConfirmedBlock, UiTransactionReturnData,
},
std::{collections::HashMap, fmt, net::SocketAddr, str::FromStr},
thiserror::Error,
Expand Down Expand Up @@ -423,6 +423,7 @@ pub struct RpcSimulateTransactionResult {
pub accounts: Option<Vec<Option<UiAccount>>>,
pub units_consumed: Option<u64>,
pub return_data: Option<UiTransactionReturnData>,
pub inner_instructions: Option<Vec<InnerInstructions>>,
}

#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, Eq)]
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 @@ -350,6 +350,7 @@ impl RpcSender for MockSender {
accounts: None,
units_consumed: None,
return_data: None,
inner_instructions: None,
},
})?,
"getMinimumBalanceForRentExemption" => json![20],
Expand Down
36 changes: 30 additions & 6 deletions rpc/src/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,9 +88,9 @@ use {
solana_streamer::socket::SocketAddrSpace,
solana_transaction_status::{
BlockEncodingOptions, ConfirmedBlock, ConfirmedTransactionStatusWithSignature,
ConfirmedTransactionWithStatusMeta, EncodedConfirmedTransactionWithStatusMeta, Reward,
RewardType, TransactionBinaryEncoding, TransactionConfirmationStatus, TransactionStatus,
UiConfirmedBlock, UiTransactionEncoding,
ConfirmedTransactionWithStatusMeta, EncodedConfirmedTransactionWithStatusMeta,
InnerInstruction, InnerInstructions, Reward, RewardType, TransactionBinaryEncoding,
TransactionConfirmationStatus, TransactionStatus, UiConfirmedBlock, UiTransactionEncoding,
},
solana_vote_program::vote_state::{VoteState, MAX_LOCKOUT_HISTORY},
spl_token_2022::{
Expand Down Expand Up @@ -3675,7 +3675,7 @@ pub mod rpc_full {
post_simulation_accounts: _,
units_consumed,
return_data,
inner_instructions: _,
inner_instructions: _, // Always `None` due to `enable_cpi_recording = false`
} = preflight_bank.simulate_transaction(transaction, false)
{
match err {
Expand All @@ -3694,6 +3694,7 @@ pub mod rpc_full {
accounts: None,
units_consumed: Some(units_consumed),
return_data: return_data.map(|return_data| return_data.into()),
inner_instructions: None,
},
}
.into());
Expand Down Expand Up @@ -3762,7 +3763,7 @@ pub mod rpc_full {
post_simulation_accounts,
units_consumed,
return_data,
inner_instructions: _,
inner_instructions,
} = bank.simulate_transaction(transaction, enable_cpi_recording);

let accounts = if let Some(config_accounts) = config_accounts {
Expand Down Expand Up @@ -3806,6 +3807,23 @@ pub mod rpc_full {
None
};

let inner_instructions = inner_instructions.map(|info| {
info.into_iter()
.enumerate()
.map(|(index, instructions)| InnerInstructions {
index: index as u8,
instructions: instructions
.into_iter()
.map(|info| InnerInstruction {
stack_height: Some(u32::from(info.stack_height)),
instruction: info.instruction,
})
.collect(),
})
.filter(|i| !i.instructions.is_empty())
.collect()
});

Ok(new_response(
bank,
RpcSimulateTransactionResult {
Expand All @@ -3814,6 +3832,7 @@ pub mod rpc_full {
accounts,
units_consumed: Some(units_consumed),
return_data: return_data.map(|return_data| return_data.into()),
inner_instructions,
},
))
}
Expand Down Expand Up @@ -5912,6 +5931,7 @@ pub mod tests {
}
],
"err":null,
"innerInstructions": null,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -5996,6 +6016,7 @@ pub mod tests {
"value":{
"accounts":null,
"err":null,
"innerInstructions":null,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -6024,6 +6045,7 @@ pub mod tests {
"value":{
"accounts":null,
"err":null,
"innerInstructions":null,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -6076,6 +6098,7 @@ pub mod tests {
"value":{
"err":"BlockhashNotFound",
"accounts":null,
"innerInstructions":null,
"logs":[],
"returnData":null,
"unitsConsumed":0,
Expand All @@ -6102,6 +6125,7 @@ pub mod tests {
"value":{
"accounts":null,
"err":null,
"innerInstructions":null,
"logs":[
"Program 11111111111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 success"
Expand Down Expand Up @@ -6482,7 +6506,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","logs":[],"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,"logs":[],"returnData":null,"unitsConsumed":0}},"id":1}"#.to_string(),
)
);

Expand Down

0 comments on commit 4d25e6a

Please sign in to comment.