From 9c606676870df4c5b66a5d78e8c8a53625d7a5a4 Mon Sep 17 00:00:00 2001 From: Sarfaraz Nawaz Date: Tue, 4 Nov 2025 23:57:15 +0530 Subject: [PATCH] feat: Add CommitDiffFromBuffer ix --- src/discriminator.rs | 2 + .../commit_diff_from_buffer.rs | 47 ++++++++++++++++ src/instruction_builder/mod.rs | 2 + src/lib.rs | 6 ++ src/processor/fast/commit_diff_from_buffer.rs | 55 +++++++++++++++++++ src/processor/fast/mod.rs | 2 + 6 files changed, 114 insertions(+) create mode 100644 src/instruction_builder/commit_diff_from_buffer.rs create mode 100644 src/processor/fast/commit_diff_from_buffer.rs diff --git a/src/discriminator.rs b/src/discriminator.rs index 8025c15..a286a4a 100644 --- a/src/discriminator.rs +++ b/src/discriminator.rs @@ -37,6 +37,8 @@ pub enum DlpDiscriminator { CallHandler = 15, /// See [crate::processor::process_commit_diff] for docs. CommitDiff = 16, + /// See [crate::processor::process_commit_diff_from_buffer] for docs. + CommitDiffFromBuffer = 17, } impl DlpDiscriminator { diff --git a/src/instruction_builder/commit_diff_from_buffer.rs b/src/instruction_builder/commit_diff_from_buffer.rs new file mode 100644 index 0000000..f1913db --- /dev/null +++ b/src/instruction_builder/commit_diff_from_buffer.rs @@ -0,0 +1,47 @@ +use borsh::to_vec; +use solana_program::instruction::Instruction; +use solana_program::system_program; +use solana_program::{instruction::AccountMeta, pubkey::Pubkey}; + +use crate::args::CommitStateFromBufferArgs; +use crate::discriminator::DlpDiscriminator; +use crate::pda::{ + commit_record_pda_from_delegated_account, commit_state_pda_from_delegated_account, + delegation_metadata_pda_from_delegated_account, delegation_record_pda_from_delegated_account, + program_config_from_program_id, validator_fees_vault_pda_from_validator, +}; + +/// Builds a commit state from buffer instruction. +/// See [crate::processor::process_commit_diff_from_buffer] for docs. +pub fn commit_diff_from_buffer( + validator: Pubkey, + delegated_account: Pubkey, + delegated_account_owner: Pubkey, + commit_state_buffer: Pubkey, + commit_args: CommitStateFromBufferArgs, +) -> Instruction { + let commit_args = to_vec(&commit_args).unwrap(); + let delegation_record_pda = delegation_record_pda_from_delegated_account(&delegated_account); + let commit_state_pda = commit_state_pda_from_delegated_account(&delegated_account); + let commit_record_pda = commit_record_pda_from_delegated_account(&delegated_account); + let validator_fees_vault_pda = validator_fees_vault_pda_from_validator(&validator); + let delegation_metadata_pda = + delegation_metadata_pda_from_delegated_account(&delegated_account); + let program_config_pda = program_config_from_program_id(&delegated_account_owner); + Instruction { + program_id: crate::id(), + accounts: vec![ + AccountMeta::new_readonly(validator, true), + AccountMeta::new_readonly(delegated_account, false), + AccountMeta::new(commit_state_pda, false), + AccountMeta::new(commit_record_pda, false), + AccountMeta::new_readonly(delegation_record_pda, false), + AccountMeta::new(delegation_metadata_pda, false), + AccountMeta::new_readonly(commit_state_buffer, false), + AccountMeta::new_readonly(validator_fees_vault_pda, false), + AccountMeta::new_readonly(program_config_pda, false), + AccountMeta::new_readonly(system_program::id(), false), + ], + data: [DlpDiscriminator::CommitDiffFromBuffer.to_vec(), commit_args].concat(), + } +} diff --git a/src/instruction_builder/mod.rs b/src/instruction_builder/mod.rs index 8ca460b..2007a42 100644 --- a/src/instruction_builder/mod.rs +++ b/src/instruction_builder/mod.rs @@ -2,6 +2,7 @@ mod call_handler; mod close_ephemeral_balance; mod close_validator_fees_vault; mod commit_diff; +mod commit_diff_from_buffer; mod commit_state; mod commit_state_from_buffer; mod delegate; @@ -19,6 +20,7 @@ pub use call_handler::*; pub use close_ephemeral_balance::*; pub use close_validator_fees_vault::*; pub use commit_diff::*; +pub use commit_diff_from_buffer::*; pub use commit_state::*; pub use commit_state_from_buffer::*; pub use delegate::*; diff --git a/src/lib.rs b/src/lib.rs index 291b2f9..967e695 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -24,6 +24,9 @@ mod processor; pub use diff::*; +// re-export +pub use rkyv; + #[cfg(feature = "log-cost")] mod cu; @@ -85,6 +88,9 @@ pub fn fast_process_instruction( DlpDiscriminator::CommitDiff => Some(processor::fast::process_commit_diff( program_id, accounts, data, )), + DlpDiscriminator::CommitDiffFromBuffer => Some( + processor::fast::process_commit_diff_from_buffer(program_id, accounts, data), + ), DlpDiscriminator::Finalize => Some(processor::fast::process_finalize( program_id, accounts, data, )), diff --git a/src/processor/fast/commit_diff_from_buffer.rs b/src/processor/fast/commit_diff_from_buffer.rs new file mode 100644 index 0000000..8c3442f --- /dev/null +++ b/src/processor/fast/commit_diff_from_buffer.rs @@ -0,0 +1,55 @@ +use crate::args::CommitStateFromBufferArgs; +use crate::processor::fast::{process_commit_state_internal, CommitStateInternalArgs}; +use crate::DiffSet; + +use borsh::BorshDeserialize; +use pinocchio::account_info::AccountInfo; +use pinocchio::program_error::ProgramError; +use pinocchio::pubkey::Pubkey; +use pinocchio::ProgramResult; +use pinocchio_log::log; + +use super::NewState; + +pub fn process_commit_diff_from_buffer( + _program_id: &Pubkey, + accounts: &[AccountInfo], + data: &[u8], +) -> ProgramResult { + let [validator, delegated_account, commit_state_account, commit_record_account, delegation_record_account, delegation_metadata_account, diff_buffer_account, validator_fees_vault, program_config_account, _system_program] = + accounts + else { + return Err(ProgramError::NotEnoughAccountKeys); + }; + + let args = + CommitStateFromBufferArgs::try_from_slice(data).map_err(|_| ProgramError::BorshIoError)?; + + let commit_record_lamports = args.lamports; + let commit_record_nonce = args.nonce; + let allow_undelegation = args.allow_undelegation; + + let diff = diff_buffer_account.try_borrow_data()?; + + let diffset = DiffSet::try_new(diff.as_ref())?; + + if diffset.segments_count() == 0 { + log!("WARN: noop; empty diff sent"); + } + + let commit_args = CommitStateInternalArgs { + commit_state_bytes: NewState::Diff(diffset), + commit_record_lamports, + commit_record_nonce, + allow_undelegation, + validator, + delegated_account, + commit_state_account, + commit_record_account, + delegation_record_account, + delegation_metadata_account, + validator_fees_vault, + program_config_account, + }; + process_commit_state_internal(commit_args) +} diff --git a/src/processor/fast/mod.rs b/src/processor/fast/mod.rs index 0472a34..94ad5cf 100644 --- a/src/processor/fast/mod.rs +++ b/src/processor/fast/mod.rs @@ -1,4 +1,5 @@ mod commit_diff; +mod commit_diff_from_buffer; mod commit_state; mod commit_state_from_buffer; mod delegate; @@ -7,6 +8,7 @@ mod undelegate; mod utils; pub use commit_diff::*; +pub use commit_diff_from_buffer::*; pub use commit_state::*; pub use commit_state_from_buffer::*; pub use delegate::*;