In the code from the project here, the processing logic is as follows:
pub struct Processor {}
impl Processor {
pub fn process_instruction(
_program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let instruction = CounterInstruction::try_from_slice(instruction_data)
.map_err(|_| ProgramError::InvalidInstructionData)?;
match instruction {
CounterInstruction::Increment => {
msg!("Instruction: Increment");
let accounts_iter = &mut accounts.iter();
let counter_ai = next_account_info(accounts_iter)?;
let mut counter = Counter::try_from_slice(&counter_ai.try_borrow_mut_data()?)?;
counter.count += 1;
counter.serialize(&mut *counter_ai.data.borrow_mut())?;
}
CounterInstruction::Decrement => {
msg!("Instruction: Decrement");
let accounts_iter = &mut accounts.iter();
let counter_ai = next_account_info(accounts_iter)?;
let mut counter = Counter::try_from_slice(&counter_ai.try_borrow_mut_data()?)?;
counter.count = counter.count.saturating_sub(1);
counter.serialize(&mut *counter_ai.data.borrow_mut())?;
}
}
Ok(())
}
}
I understand this code is where the data in the counter
account is being updated. Specifically for the increment this code:
counter.count += 1;
counter.serialize(&mut *counter_ai.data.borrow_mut())?;
What I do not understand is how this code actually leads to changes in the counter
data and how that get saved.
If it were a typical program using a database, the pseudo code could look something like this:
counter.count += 1; // updated the count
dbClient.save(counter) // use a client to the db to persist the updated value
but in the Solana code base I see:
counter.serialize(&mut *counter_ai.data.borrow_mut())?;
How exactly does calling serialize
on the counter object, while passing it &mut *counter_ai.data.borrow_mut()
causes the solana runtime to update the data
value?