The Batch instruction (discriminator 255) allows executing multiple Token-2022 instructions in a single CPI invocation. This is significantly more compute-unit (CU) efficient because the base CPI invoke units (currently 1000 CUs) are consumed only once for the entire batch, rather than once per instruction.
To use batching:
- Calculate the required
ACCOUNTS_LEN and DATA_LEN by summing the requirements of all intended instructions. - Create uninitialized arrays for
data, instruction_accounts, and accounts using MaybeUninit. - Initialize a
Batch instance using Batch::new(). - Convert individual instructions into the batch using the
.into_batch(&mut batch) method. - Call
batch.invoke() to execute the entire sequence.
use {
core::mem::MaybeUninit,
pinocchio_token_2022::instructions::{
Batch, InitializeAccount, InitializeMint, IntoBatch, MintTo,
},
};
// 1. Determine maximum lengths
const ACCOUNTS_LEN: usize = InitializeMint::ACCOUNTS_LEN
+ InitializeAccount::ACCOUNTS_LEN
+ MintTo::MAX_ACCOUNTS_LEN;
const DATA_LEN: usize = Batch::header_data_len(3)
+ InitializeMint::MAX_DATA_LEN
+ InitializeAccount::DATA_LEN
+ MintTo::DATA_LEN;
// 2. Create uninitialized arrays
let mut data = [const { MaybeUninit::uninit() }; DATA_LEN];
let mut instruction_accounts = [const { MaybeUninit::uninit() }; ACCOUNTS_LEN];
let mut accounts = [const { MaybeUninit::uninit() }; ACCOUNTS_LEN];
// 3. Create the batch
let mut batch = Batch::new(&mut data, &mut instruction_accounts, &mut accounts)?;
// 4. Add instructions to the batch
InitializeMint::new(
mint_account,
rent_sysvar,
9,
&authority,
Some(&authority),
).into_batch(&mut batch)?;
InitializeAccount::new(
token_account,
mint_account,
owner,
rent_sysvar
).into_batch(&mut batch)?;
MintTo::new(
mint_account,
token_account,
authority_account,
1000
).into_batch(&mut batch)?;
// 5. Invoke the batch
batch.invoke()?;