Skip to content

Commit 2e4997e

Browse files
committed
feat: add CommitFinalizeFromBuffer
1 parent ee84e25 commit 2e4997e

9 files changed

Lines changed: 193 additions & 1 deletion

File tree

src/discriminator.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ pub enum DlpDiscriminator {
4747

4848
/// See [crate::processor::process_commit_finalize] for docs.
4949
CommitFinalize = 20,
50+
51+
/// See [crate::processor::process_commit_finalize_from_buffer] for docs.
52+
CommitFinalizeFromBuffer = 21,
5053
}
5154

5255
impl DlpDiscriminator {
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
use solana_program::instruction::Instruction;
2+
use solana_program::system_program;
3+
use solana_program::{instruction::AccountMeta, pubkey::Pubkey};
4+
5+
use crate::args::{CommitBumps, CommitFinalizeArgs};
6+
use crate::discriminator::DlpDiscriminator;
7+
use crate::pod_view::PodView;
8+
use crate::{
9+
delegation_metadata_seeds_from_delegated_account,
10+
delegation_record_seeds_from_delegated_account, program_config_seeds_from_program_id,
11+
total_size_budget, validator_fees_vault_seeds_from_validator, AccountSizeClass,
12+
DLP_PROGRAM_DATA_SIZE_CLASS,
13+
};
14+
15+
/// Builds a commit state from buffer instruction.
16+
/// See [crate::processor::process_commit_diff_from_buffer] for docs.
17+
pub fn commit_finalize_from_buffer(
18+
validator: Pubkey,
19+
delegated_account: Pubkey,
20+
delegated_account_owner: Pubkey,
21+
data_buffer: Pubkey,
22+
commit_args: &mut CommitFinalizeArgs,
23+
) -> Instruction {
24+
let delegation_record = Pubkey::find_program_address(
25+
delegation_record_seeds_from_delegated_account!(delegated_account),
26+
&crate::id(),
27+
);
28+
29+
let validator_fees_vault = Pubkey::find_program_address(
30+
validator_fees_vault_seeds_from_validator!(validator),
31+
&crate::id(),
32+
);
33+
34+
let delegation_metadata = Pubkey::find_program_address(
35+
delegation_metadata_seeds_from_delegated_account!(delegated_account),
36+
&crate::id(),
37+
);
38+
39+
let program_config = Pubkey::find_program_address(
40+
program_config_seeds_from_program_id!(delegated_account_owner),
41+
&crate::id(),
42+
);
43+
44+
// save the bumps in the args
45+
commit_args.bumps = CommitBumps {
46+
delegation_record: delegation_record.1,
47+
delegation_metadata: delegation_metadata.1,
48+
validator_fees_vault: validator_fees_vault.1,
49+
program_config: program_config.1,
50+
};
51+
52+
Instruction {
53+
program_id: crate::id(),
54+
accounts: vec![
55+
AccountMeta::new_readonly(validator, true),
56+
AccountMeta::new(delegated_account, false),
57+
AccountMeta::new_readonly(delegation_record.0, false),
58+
AccountMeta::new(delegation_metadata.0, false),
59+
AccountMeta::new_readonly(data_buffer, false),
60+
AccountMeta::new_readonly(validator_fees_vault.0, false),
61+
AccountMeta::new_readonly(program_config.0, false),
62+
AccountMeta::new_readonly(system_program::id(), false),
63+
],
64+
data: [
65+
DlpDiscriminator::CommitFinalizeFromBuffer.to_vec(),
66+
commit_args.to_bytes(),
67+
]
68+
.concat(),
69+
}
70+
}
71+
72+
///
73+
/// Returns accounts-data-size budget for commit_diff_from_buffer instruction.
74+
///
75+
/// This value can be used with ComputeBudgetInstruction::SetLoadedAccountsDataSizeLimit
76+
///
77+
pub fn commit_finalize_from_buffer_size_budget(delegated_account: AccountSizeClass) -> u32 {
78+
total_size_budget(&[
79+
DLP_PROGRAM_DATA_SIZE_CLASS,
80+
AccountSizeClass::Tiny, // validator
81+
delegated_account, // delegated_account
82+
AccountSizeClass::Tiny, // delegation_record_pda
83+
AccountSizeClass::Tiny, // delegation_metadata_pda
84+
delegated_account, // data_buffer
85+
AccountSizeClass::Tiny, // validator_fees_vault_pda
86+
AccountSizeClass::Tiny, // program_config_pda
87+
AccountSizeClass::Tiny, // system_program
88+
])
89+
}

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;
@@ -24,6 +25,7 @@ pub use close_validator_fees_vault::*;
2425
pub use commit_diff::*;
2526
pub use commit_diff_from_buffer::*;
2627
pub use commit_finalize::*;
28+
pub use commit_finalize_from_buffer::*;
2729
pub use commit_state::*;
2830
pub use commit_state_from_buffer::*;
2931
pub use delegate::*;

src/lib.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ pub fn fast_process_instruction(
121121
DlpDiscriminator::CommitFinalize => Some(processor::fast::process_commit_finalize(
122122
program_id, accounts, data,
123123
)),
124+
DlpDiscriminator::CommitFinalizeFromBuffer => Some(
125+
processor::fast::process_commit_finalize_from_buffer(program_id, accounts, data),
126+
),
124127
DlpDiscriminator::Finalize => Some(processor::fast::process_finalize(
125128
program_id, accounts, data,
126129
)),
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
use pinocchio::{
2+
account_info::AccountInfo, program_error::ProgramError, pubkey::Pubkey, ProgramResult,
3+
};
4+
use pinocchio_log::log;
5+
6+
use crate::args::CommitFinalizeArgs;
7+
use crate::pod_view::PodView;
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+
/// Instruction Data: CommitFinalizeArgs
28+
///
29+
/// Requirements:
30+
///
31+
/// - delegation record is initialized
32+
/// - delegation metadata is initialized
33+
/// - validator fees vault is initialized
34+
/// - program config is initialized
35+
/// - commit state is uninitialized
36+
/// - commit record is uninitialized
37+
/// - delegated account holds at least the lamports indicated in the delegation record
38+
/// - account was not committed at a later slot
39+
///
40+
/// Steps:
41+
/// 1. Check that the pda is delegated
42+
/// 2. Init a new PDA to store the new state
43+
/// 3. Copy the new state to the new PDA
44+
/// 4. Init a new PDA to store the record of the new state commitment
45+
pub fn process_commit_finalize_from_buffer(
46+
_program_id: &Pubkey,
47+
accounts: &[AccountInfo],
48+
data: &[u8],
49+
) -> ProgramResult {
50+
let [
51+
validator, // force multi-line
52+
delegated_account,
53+
delegation_record_account,
54+
delegation_metadata_account,
55+
data_account, // full bytes or diff
56+
validator_fees_vault,
57+
program_config_account,
58+
_system_program,
59+
] = require_n_accounts!(accounts, 8);
60+
61+
let args = CommitFinalizeArgs::try_view_from(data)?;
62+
63+
let data = data_account.try_borrow_data()?;
64+
let commit_args = CommitFinalizeInternalArgs {
65+
bumps: &args.bumps,
66+
new_state: match args.data_is_diff {
67+
0 => NewState::FullBytes(&data),
68+
1 => {
69+
let diffset = DiffSet::try_new(data.as_ref())?;
70+
if diffset.segments_count() == 0 {
71+
log!("WARN: noop; empty diff sent");
72+
}
73+
NewState::Diff(diffset)
74+
}
75+
_ => return Err(ProgramError::InvalidInstructionData),
76+
},
77+
commit_id: args.commit_id,
78+
allow_undelegation: args.allow_undelegation == 1,
79+
validator,
80+
delegated_account,
81+
delegation_record_account,
82+
delegation_metadata_account,
83+
validator_fees_vault,
84+
program_config_account,
85+
};
86+
87+
process_commit_finalize_internal(commit_args)
88+
}

src/processor/fast/commit_finalize_internal.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ pub(crate) fn process_commit_finalize_internal(
204204
// .invoke()?;
205205
// }
206206

207+
// TODO (snawaz): in v2, maybe we do not need it (as we have already checked the validator
208+
// earlier), or maybe we move it to delegate ix.
209+
//
207210
// Load the program configuration and validate it, if any
208211

209212
// OPTIMIZE 1

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;
@@ -13,6 +14,7 @@ mod utils;
1314
pub use commit_diff::*;
1415
pub use commit_diff_from_buffer::*;
1516
pub use commit_finalize::*;
17+
pub use commit_finalize_from_buffer::*;
1618
pub use commit_state::*;
1719
pub use commit_state_from_buffer::*;
1820
pub use delegate::*;

src/processor/fast/utils/requires.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,8 @@ pub fn require_owned_pda(
404404
if !pubkey_eq(info.owner(), owner) {
405405
log!("Invalid account owner for {}:", label);
406406
pubkey::log(info.key());
407+
pubkey::log(info.owner());
408+
pubkey::log(owner);
407409
return Err(ProgramError::InvalidAccountOwner);
408410
}
409411
Ok(())

src/processor/init_validator_fees_vault.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::validator_fees_vault_seeds_from_validator;
1616
/// Accounts:
1717
///
1818
/// 0; `[signer]` payer
19-
/// 1; `[signer]` admin that controls the vault
19+
/// 1; `[signer]` magicblock admin that controls the vault
2020
/// 2; `[]` validator_identity
2121
/// 3; `[]` validator_fees_vault_pda
2222
/// 4; `[]` system_program

0 commit comments

Comments
 (0)