Support for returnData in simulate transaction (#26499)

feat(web3.js): add Support for returnData in simulate transaction
This commit is contained in:
Athar Mohammad 2022-07-12 17:37:17 +05:30 committed by GitHub
parent 03738d6766
commit d0d3ad7166
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 90 additions and 2 deletions

View File

@ -711,13 +711,20 @@ export type SimulatedTransactionAccountInfo = {
rentEpoch?: number; rentEpoch?: number;
}; };
export type TransactionReturnDataEncoding = 'base64';
export type TransactionReturnData = {
programId: string;
data: [string, TransactionReturnDataEncoding];
};
export type SimulatedTransactionResponse = { export type SimulatedTransactionResponse = {
err: TransactionError | string | null; err: TransactionError | string | null;
logs: Array<string> | null; logs: Array<string> | null;
accounts?: (SimulatedTransactionAccountInfo | null)[] | null; accounts?: (SimulatedTransactionAccountInfo | null)[] | null;
unitsConsumed?: number; unitsConsumed?: number;
returnData?: TransactionReturnData | null;
}; };
const SimulatedTransactionResponseStruct = jsonRpcResultAndContext( const SimulatedTransactionResponseStruct = jsonRpcResultAndContext(
pick({ pick({
err: nullable(union([pick({}), string()])), err: nullable(union([pick({}), string()])),
@ -738,6 +745,14 @@ const SimulatedTransactionResponseStruct = jsonRpcResultAndContext(
), ),
), ),
unitsConsumed: optional(number()), unitsConsumed: optional(number()),
returnData: optional(
nullable(
pick({
programId: string(),
data: tuple([string(), literal('base64')]),
}),
),
),
}), }),
); );

View File

@ -147,6 +147,25 @@ if (process.env.TEST_LIVE) {
); );
}); });
it('simulate transaction with returnData', async () => {
const simulatedTransaction = new Transaction().add({
keys: [
{pubkey: payerAccount.publicKey, isSigner: true, isWritable: true},
],
programId: program.publicKey,
});
const {err, returnData} = (
await connection.simulateTransaction(simulatedTransaction, [
payerAccount,
])
).value;
const expectedReturnData = new Uint8Array([1, 2, 3]);
var decodedData = Buffer.from(returnData.data[0], returnData.data[1]);
expect(err).to.be.null;
expect(returnData.programId).to.eql(program.publicKey.toString());
expect(decodedData).to.eql(expectedReturnData);
});
it('deprecated - simulate transaction without signature verification', async () => { it('deprecated - simulate transaction without signature verification', async () => {
const simulatedTransaction = new Transaction().add({ const simulatedTransaction = new Transaction().add({
keys: [ keys: [

View File

@ -3756,6 +3756,53 @@ describe('Connection', function () {
verifySignatureStatus(response, expectedErr); verifySignatureStatus(response, expectedErr);
}); });
if (mockServer) {
it('returnData on simulateTransaction', async () => {
const tx = new Transaction();
tx.feePayer = Keypair.generate().publicKey;
const getLatestBlockhashResponse = {
method: 'getLatestBlockhash',
params: [],
value: {
blockhash: 'CSymwgTNX1j3E4qhKfJAUE41nBWEwXufoYryPbkde5RR',
feeCalculator: {
lamportsPerSignature: 5000,
},
lastValidBlockHeight: 51,
},
withContext: true,
};
const simulateTransactionResponse = {
method: 'simulateTransaction',
params: [],
value: {
err: null,
accounts: null,
logs: [
'Program 83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri invoke [1]',
'Program 83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri consumed 2366 of 1400000 compute units',
'Program return: 83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri KgAAAAAAAAA=',
'Program 83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri success',
],
returnData: {
data: ['KgAAAAAAAAA==', 'base64'],
programId: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri',
},
unitsConsumed: 2366,
},
withContext: true,
};
await mockRpcResponse(getLatestBlockhashResponse);
await mockRpcResponse(simulateTransactionResponse);
const response = (await connection.simulateTransaction(tx)).value;
expect(response.returnData).to.eql({
data: ['KgAAAAAAAAA==', 'base64'],
programId: '83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri',
});
});
}
if (process.env.TEST_LIVE) { if (process.env.TEST_LIVE) {
it('simulate transaction with message', async () => { it('simulate transaction with message', async () => {
connection._commitment = 'confirmed'; connection._commitment = 'confirmed';

View File

@ -1,7 +1,8 @@
//! Example Rust-based BPF program that prints out the parameters passed to it //! Example Rust-based BPF program that prints out the parameters passed to it
use solana_program::{ use solana_program::{
account_info::AccountInfo, entrypoint::ProgramResult, log::*, msg, pubkey::Pubkey, account_info::AccountInfo, entrypoint::ProgramResult, log::*, msg, program::set_return_data,
pubkey::Pubkey,
}; };
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
@ -55,6 +56,12 @@ fn process_instruction(
panic!(); panic!();
} }
{
// return data in simulate transaction
let return_data: &[u8] = &[1, 2, 3];
set_return_data(return_data);
}
Ok(()) Ok(())
} }