Skip to content

Commit 8d7aa67

Browse files
committed
feat: add CommitFinalizeFromBuffer
1 parent b2d1983 commit 8d7aa67

7 files changed

Lines changed: 173 additions & 0 deletions

File tree

src/args/commit_state.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,18 @@ pub struct CommitStateFromBufferArgs {
4141
pub allow_undelegation: bool,
4242
}
4343

44+
#[derive(Default, Debug, BorshSerialize, BorshDeserialize)]
45+
pub struct CommitFinalizeFromBufferArgs {
46+
/// "Nonce" of an account. Updates are submitted historically and nonce incremented by 1
47+
/// Deprecated: The ephemeral slot at which the account data is committed
48+
pub nonce: u64,
49+
/// The lamports that the account holds in the ephemeral validator
50+
pub lamports: u64,
51+
/// Whether the account can be undelegated after the commit completes
52+
pub allow_undelegation: u8, // 0 (false) or 1 (true)
53+
pub data_is_diff: u8, // 0 (false) or 1 (true)
54+
}
55+
4456
#[derive(Default, Debug, BorshSerialize)]
4557
pub struct CommitDiffArgs {
4658
/// The account diff

src/discriminator.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,8 @@ pub enum DlpDiscriminator {
4141
CommitDiffFromBuffer = 17,
4242
/// See [crate::processor::process_commit_finalize] for docs.
4343
CommitFinalize = 18,
44+
/// See [crate::processor::process_commit_finalize_from_buffer] for docs.
45+
CommitFinalizeFromBuffer = 19,
4446
}
4547

4648
impl DlpDiscriminator {
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
use borsh::to_vec;
2+
use solana_program::instruction::Instruction;
3+
use solana_program::system_program;
4+
use solana_program::{instruction::AccountMeta, pubkey::Pubkey};
5+
6+
use crate::args::CommitFinalizeFromBufferArgs;
7+
use crate::discriminator::DlpDiscriminator;
8+
use crate::pda::{
9+
delegation_metadata_pda_from_delegated_account, delegation_record_pda_from_delegated_account,
10+
program_config_from_program_id, validator_fees_vault_pda_from_validator,
11+
};
12+
use crate::{total_size_budget, AccountSizeClass, DLP_PROGRAM_DATA_SIZE_CLASS};
13+
14+
/// Builds a commit state from buffer instruction.
15+
/// See [crate::processor::process_commit_diff_from_buffer] for docs.
16+
pub fn commit_finalize_from_buffer(
17+
validator: Pubkey,
18+
delegated_account: Pubkey,
19+
delegated_account_owner: Pubkey,
20+
data_buffer: Pubkey,
21+
commit_args: CommitFinalizeFromBufferArgs,
22+
) -> Instruction {
23+
let commit_args = to_vec(&commit_args).unwrap();
24+
let delegation_record_pda = delegation_record_pda_from_delegated_account(&delegated_account);
25+
let validator_fees_vault_pda = validator_fees_vault_pda_from_validator(&validator);
26+
let delegation_metadata_pda =
27+
delegation_metadata_pda_from_delegated_account(&delegated_account);
28+
let program_config_pda = program_config_from_program_id(&delegated_account_owner);
29+
Instruction {
30+
program_id: crate::id(),
31+
accounts: vec![
32+
AccountMeta::new_readonly(validator, true),
33+
AccountMeta::new_readonly(delegated_account, false),
34+
AccountMeta::new_readonly(delegation_record_pda, false),
35+
AccountMeta::new(delegation_metadata_pda, false),
36+
AccountMeta::new_readonly(data_buffer, false),
37+
AccountMeta::new_readonly(validator_fees_vault_pda, false),
38+
AccountMeta::new_readonly(program_config_pda, false),
39+
AccountMeta::new_readonly(system_program::id(), false),
40+
],
41+
data: [
42+
DlpDiscriminator::CommitFinalizeFromBuffer.to_vec(),
43+
commit_args,
44+
]
45+
.concat(),
46+
}
47+
}
48+
49+
///
50+
/// Returns accounts-data-size budget for commit_diff_from_buffer instruction.
51+
///
52+
/// This value can be used with ComputeBudgetInstruction::SetLoadedAccountsDataSizeLimit
53+
///
54+
pub fn commit_finalize_from_buffer_size_budget(delegated_account: AccountSizeClass) -> u32 {
55+
total_size_budget(&[
56+
DLP_PROGRAM_DATA_SIZE_CLASS,
57+
AccountSizeClass::Tiny, // validator
58+
delegated_account, // delegated_account
59+
AccountSizeClass::Tiny, // delegation_record_pda
60+
AccountSizeClass::Tiny, // delegation_metadata_pda
61+
delegated_account, // data_buffer
62+
AccountSizeClass::Tiny, // validator_fees_vault_pda
63+
AccountSizeClass::Tiny, // program_config_pda
64+
AccountSizeClass::Tiny, // system_program
65+
])
66+
}

src/instruction_builder/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod close_validator_fees_vault;
44
mod commit_diff;
55
mod commit_diff_from_buffer;
66
mod commit_finalize;
7+
mod commit_finalize_from_buffer;
78
mod commit_state;
89
mod commit_state_from_buffer;
910
mod delegate;
@@ -23,6 +24,7 @@ pub use close_validator_fees_vault::*;
2324
pub use commit_diff::*;
2425
pub use commit_diff_from_buffer::*;
2526
pub use commit_finalize::*;
27+
pub use commit_finalize_from_buffer::*;
2628
pub use commit_state::*;
2729
pub use commit_state_from_buffer::*;
2830
pub use delegate::*;

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,9 @@ pub fn fast_process_instruction(
116116
DlpDiscriminator::CommitFinalize => Some(processor::fast::process_commit_finalize(
117117
program_id, accounts, data,
118118
)),
119+
DlpDiscriminator::CommitFinalizeFromBuffer => Some(
120+
processor::fast::process_commit_finalize_from_buffer(program_id, accounts, data),
121+
),
119122
DlpDiscriminator::Finalize => Some(processor::fast::process_finalize(
120123
program_id, accounts, data,
121124
)),
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use borsh::BorshDeserialize;
2+
use pinocchio::{
3+
account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult,
4+
};
5+
use pinocchio_log::log;
6+
7+
use crate::args::CommitFinalizeFromBufferArgs;
8+
use crate::processor::fast::{
9+
commit_finalize_internal::{process_commit_finalize_internal, CommitFinalizeInternalArgs},
10+
NewState,
11+
};
12+
use crate::{require_n_accounts, DiffSet};
13+
14+
/// Commit a new state of a delegated PDA
15+
///
16+
/// Accounts:
17+
///
18+
/// 0: `[signer]` the validator requesting the commit
19+
/// 1: `[]` the delegated account
20+
/// 2: `[writable]` the PDA storing the new state
21+
/// 3: `[writable]` the PDA storing the commit record
22+
/// 4: `[]` the delegation record
23+
/// 5: `[writable]` the delegation metadata
24+
/// 6: `[]` the validator fees vault
25+
/// 7: `[]` the program config account
26+
///
27+
/// Requirements:
28+
///
29+
/// - delegation record is initialized
30+
/// - delegation metadata is initialized
31+
/// - validator fees vault is initialized
32+
/// - program config is initialized
33+
/// - commit state is uninitialized
34+
/// - commit record is uninitialized
35+
/// - delegated account holds at least the lamports indicated in the delegation record
36+
/// - account was not committed at a later slot
37+
///
38+
/// Steps:
39+
/// 1. Check that the pda is delegated
40+
/// 2. Init a new PDA to store the new state
41+
/// 3. Copy the new state to the new PDA
42+
/// 4. Init a new PDA to store the record of the new state commitment
43+
pub fn process_commit_finalize_from_buffer(
44+
_program_id: &Pubkey,
45+
accounts: &[AccountInfo],
46+
data: &[u8],
47+
) -> ProgramResult {
48+
let [
49+
validator, // force multi-line
50+
delegated_account,
51+
delegation_record_account,
52+
delegation_metadata_account,
53+
data_account, // full bytes or diff
54+
validator_fees_vault,
55+
program_config_account,
56+
_system_program,
57+
] = require_n_accounts!(accounts, 8);
58+
59+
let args = CommitFinalizeFromBufferArgs::try_from_slice(data)
60+
.map_err(|_| ProgramError::BorshIoError)?;
61+
62+
let data = data_account.try_borrow_data()?;
63+
let commit_args = CommitFinalizeInternalArgs {
64+
new_state: match args.data_is_diff {
65+
0 => NewState::FullBytes(&data),
66+
1 => {
67+
let diffset = DiffSet::try_new(data.as_ref())?;
68+
if diffset.segments_count() == 0 {
69+
log!("WARN: noop; empty diff sent");
70+
}
71+
NewState::Diff(diffset)
72+
}
73+
_ => return Err(ProgramError::InvalidInstructionData),
74+
},
75+
commit_record_nonce: args.nonce,
76+
allow_undelegation: args.allow_undelegation == 1,
77+
validator,
78+
delegated_account,
79+
delegation_record_account,
80+
delegation_metadata_account,
81+
validator_fees_vault,
82+
program_config_account,
83+
};
84+
85+
process_commit_finalize_internal(commit_args)
86+
}

src/processor/fast/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod commit_diff;
22
mod commit_diff_from_buffer;
33
mod commit_finalize;
4+
mod commit_finalize_from_buffer;
45
mod commit_finalize_internal;
56
mod commit_state;
67
mod commit_state_from_buffer;
@@ -12,6 +13,7 @@ mod utils;
1213
pub use commit_diff::*;
1314
pub use commit_diff_from_buffer::*;
1415
pub use commit_finalize::*;
16+
pub use commit_finalize_from_buffer::*;
1517
pub use commit_state::*;
1618
pub use commit_state_from_buffer::*;
1719
pub use delegate::*;

0 commit comments

Comments
 (0)