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:
parent
45a2a701de
commit
9caf9e8f17
209
rpc/src/rpc.rs
209
rpc/src/rpc.rs
|
@ -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() {
|
||||
|
|
Loading…
Reference in New Issue