rpc: add tests for simulate transaction inner instructions (#34495)

* rpc: add tests for simulate transaction inner instructions

* update encoding

* take out extra test case
This commit is contained in:
Joe C 2024-01-22 19:27:27 -05:00 committed by GitHub
parent 45a2a701de
commit 9caf9e8f17
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 209 additions and 0 deletions

View File

@ -6294,6 +6294,215 @@ pub mod tests {
assert_eq!(result, expected);
}
#[test]
fn test_rpc_simulate_transaction_with_inner_instructions() {
let rpc = RpcHandler::start();
let bank = rpc.working_bank();
let recent_blockhash = bank.confirmed_last_blockhash();
let RpcHandler {
ref meta, ref io, ..
} = rpc;
let recent_slot = 123;
let mut slot_hashes = SlotHashes::default();
slot_hashes.add(recent_slot, Hash::new_unique());
bank.set_sysvar_for_tests(&slot_hashes);
let lookup_table_authority = Keypair::new();
let lookup_table_space = solana_sdk::address_lookup_table::state::LOOKUP_TABLE_META_SIZE;
let lookup_table_lamports = bank.get_minimum_balance_for_rent_exemption(lookup_table_space);
let (instruction, lookup_table_address) =
solana_sdk::address_lookup_table::instruction::create_lookup_table(
lookup_table_authority.pubkey(),
rpc.mint_keypair.pubkey(),
recent_slot,
);
let tx = Transaction::new_signed_with_payer(
&[instruction],
Some(&rpc.mint_keypair.pubkey()),
&[&rpc.mint_keypair],
recent_blockhash,
);
let tx_serialized_encoded =
base64::prelude::BASE64_STANDARD.encode(serialize(&tx).unwrap());
// Simulation bank must be frozen
bank.freeze();
// `innerInstructions` not provided, should not be in response
let req = format!(
r#"{{"jsonrpc":"2.0",
"id":1,
"method":"simulateTransaction",
"params":[
"{}",
{{ "encoding": "base64" }}
]
}}"#,
tx_serialized_encoded,
);
let res = io.handle_request_sync(&req, meta.clone());
let expected = json!({
"jsonrpc": "2.0",
"result": {
"context": {"slot": 0, "apiVersion": RpcApiVersion::default()},
"value":{
"accounts": null,
"err":null,
"innerInstructions": null,
"logs":[
"Program AddressLookupTab1e1111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program AddressLookupTab1e1111111111111111111111111 success"
],
"returnData":null,
"unitsConsumed":1200,
}
},
"id": 1,
});
let expected: Response =
serde_json::from_value(expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(result, expected);
// `innerInstructions` provided as `false`, should not be in response
let req = format!(
r#"{{"jsonrpc":"2.0",
"id":1,
"method":"simulateTransaction",
"params":[
"{}",
{{ "innerInstructions": false, "encoding": "base64" }}
]
}}"#,
tx_serialized_encoded,
);
let res = io.handle_request_sync(&req, meta.clone());
let expected = json!({
"jsonrpc": "2.0",
"result": {
"context": {"slot": 0, "apiVersion": RpcApiVersion::default()},
"value":{
"accounts": null,
"err":null,
"innerInstructions": null,
"logs":[
"Program AddressLookupTab1e1111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program AddressLookupTab1e1111111111111111111111111 success"
],
"returnData":null,
"unitsConsumed":1200,
}
},
"id": 1,
});
let expected: Response =
serde_json::from_value(expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(result, expected);
// `innerInstructions` provided as `true`, should have parsed inner instructions
let req = format!(
r#"{{"jsonrpc":"2.0",
"id":1,
"method":"simulateTransaction",
"params":[
"{}",
{{ "innerInstructions": true, "encoding": "base64" }}
]
}}"#,
tx_serialized_encoded,
);
let res = io.handle_request_sync(&req, meta.clone());
let expected = json!({
"jsonrpc": "2.0",
"result": {
"context": {"slot": 0, "apiVersion": RpcApiVersion::default()},
"value":{
"accounts": null,
"err":null,
"innerInstructions": [
{
"index": 0,
"instructions": [
{
"parsed": {
"info": {
"destination": lookup_table_address.to_string(),
"lamports": lookup_table_lamports,
"source": rpc.mint_keypair.pubkey().to_string()
},
"type": "transfer"
},
"program": "system",
"programId": "11111111111111111111111111111111",
"stackHeight": 2
},
{
"parsed": {
"info": {
"account": lookup_table_address.to_string(),
"space": lookup_table_space
},
"type": "allocate"
},
"program": "system",
"programId": "11111111111111111111111111111111",
"stackHeight": 2
},
{
"parsed": {
"info": {
"account": lookup_table_address.to_string(),
"owner": "AddressLookupTab1e1111111111111111111111111"
},
"type": "assign"
},
"program": "system",
"programId": "11111111111111111111111111111111",
"stackHeight": 2
}
]
}
],
"logs":[
"Program AddressLookupTab1e1111111111111111111111111 invoke [1]",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program 11111111111111111111111111111111 invoke [2]",
"Program 11111111111111111111111111111111 success",
"Program AddressLookupTab1e1111111111111111111111111 success"
],
"returnData":null,
"unitsConsumed":1200,
}
},
"id": 1,
});
let expected: Response =
serde_json::from_value(expected).expect("expected response deserialization");
let result: Response = serde_json::from_str(&res.expect("actual response"))
.expect("actual response deserialization");
assert_eq!(result, expected);
}
#[test]
#[should_panic(expected = "simulation bank must be frozen")]
fn test_rpc_simulate_transaction_panic_on_unfrozen_bank() {