-
Notifications
You must be signed in to change notification settings - Fork 26
feat: Execute CommitDiff as BufferTask #616
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: snawaz/commit-diff
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,7 +1,7 @@ | ||
| use std::sync::Arc; | ||
|
|
||
| use dlp::{ | ||
| args::{CommitDiffArgs, CommitStateArgs}, | ||
| args::{CommitDiffArgs, CommitStateArgs, CommitStateFromBufferArgs}, | ||
| compute_diff, | ||
| }; | ||
| use dyn_clone::DynClone; | ||
|
|
@@ -53,7 +53,6 @@ pub enum PreparationState { | |
| Cleanup(CleanupTask), | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| #[derive(Copy, Clone, PartialEq, Eq, Debug)] | ||
| pub enum TaskStrategy { | ||
| Args, | ||
|
|
@@ -153,7 +152,7 @@ impl CommitTaskBuilder { | |
| allow_undelegation, | ||
| committed_account, | ||
| base_account, | ||
| force_commit_state: false, | ||
| strategy: TaskStrategy::Args, | ||
| } | ||
| } | ||
| } | ||
|
|
@@ -164,29 +163,46 @@ pub struct CommitTask { | |
| pub allow_undelegation: bool, | ||
| pub committed_account: CommittedAccount, | ||
| base_account: Option<Account>, | ||
| force_commit_state: bool, | ||
| strategy: TaskStrategy, | ||
| } | ||
|
|
||
| impl CommitTask { | ||
| pub fn is_commit_diff(&self) -> bool { | ||
| !self.force_commit_state | ||
| && self.committed_account.account.data.len() | ||
| > CommitTaskBuilder::COMMIT_STATE_SIZE_THRESHOLD | ||
| && self.base_account.is_some() | ||
| } | ||
|
|
||
| pub fn force_commit_state(&mut self) { | ||
| self.force_commit_state = true; | ||
| pub fn switch_to_buffer_strategy(mut self) -> Self { | ||
| self.strategy = TaskStrategy::Buffer; | ||
| self | ||
| } | ||
|
|
||
| pub fn create_commit_ix(&self, validator: &Pubkey) -> Instruction { | ||
| if let Some(fetched_account) = self.base_account.as_ref() { | ||
| self.create_commit_diff_ix(validator, fetched_account) | ||
| } else { | ||
| self.create_commit_state_ix(validator) | ||
| match self.strategy { | ||
| TaskStrategy::Args => { | ||
| if let Some(base_account) = self.base_account.as_ref() { | ||
| self.create_commit_diff_ix(validator, base_account) | ||
| } else { | ||
| self.create_commit_state_ix(validator) | ||
| } | ||
| } | ||
| TaskStrategy::Buffer => { | ||
| if let Some(base_account) = self.base_account.as_ref() { | ||
| self.create_commit_diff_from_buffer_ix( | ||
| validator, | ||
| base_account, | ||
| ) | ||
| } else { | ||
| self.create_commit_state_from_buffer_ix(validator) | ||
| } | ||
| } | ||
| } | ||
| } | ||
|
|
||
| pub fn compute_diff(&self) -> Option<dlp::rkyv::AlignedVec> { | ||
| self.base_account.as_ref().map(|base_account| { | ||
| compute_diff( | ||
| base_account.data(), | ||
| self.committed_account.account.data(), | ||
| ) | ||
| }) | ||
| } | ||
|
|
||
|
Comment on lines
+197
to
+205
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Reuse
Not a bug, but you could slightly simplify and DRY this by delegating to let diff = self
.compute_diff()
.expect("base_account must be Some when using CommitDiff");before constructing Also applies to: 220-232 🤖 Prompt for AI Agents |
||
| fn create_commit_state_ix(&self, validator: &Pubkey) -> Instruction { | ||
| let args = CommitStateArgs { | ||
| nonce: self.commit_id, | ||
|
|
@@ -205,17 +221,13 @@ impl CommitTask { | |
| fn create_commit_diff_ix( | ||
| &self, | ||
| validator: &Pubkey, | ||
| fetched_account: &Account, | ||
| base_account: &Account, | ||
| ) -> Instruction { | ||
| if self.force_commit_state { | ||
| return self.create_commit_state_ix(validator); | ||
| } | ||
|
|
||
| let args = CommitDiffArgs { | ||
| nonce: self.commit_id, | ||
| lamports: self.committed_account.account.lamports, | ||
| diff: compute_diff( | ||
| fetched_account.data(), | ||
| base_account.data(), | ||
| self.committed_account.account.data(), | ||
| ) | ||
| .to_vec(), | ||
coderabbitai[bot] marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
@@ -229,6 +241,57 @@ impl CommitTask { | |
| args, | ||
| ) | ||
| } | ||
|
|
||
| fn create_commit_state_from_buffer_ix( | ||
| &self, | ||
| validator: &Pubkey, | ||
| ) -> Instruction { | ||
| let commit_id_slice = self.commit_id.to_le_bytes(); | ||
| let (commit_buffer_pubkey, _) = | ||
| magicblock_committor_program::pdas::buffer_pda( | ||
| validator, | ||
| &self.committed_account.pubkey, | ||
| &commit_id_slice, | ||
| ); | ||
|
|
||
| dlp::instruction_builder::commit_state_from_buffer( | ||
| *validator, | ||
| self.committed_account.pubkey, | ||
| self.committed_account.account.owner, | ||
| commit_buffer_pubkey, | ||
| CommitStateFromBufferArgs { | ||
| nonce: self.commit_id, | ||
| lamports: self.committed_account.account.lamports, | ||
| allow_undelegation: self.allow_undelegation, | ||
| }, | ||
| ) | ||
| } | ||
|
|
||
| fn create_commit_diff_from_buffer_ix( | ||
| &self, | ||
| validator: &Pubkey, | ||
| _fetched_account: &Account, | ||
| ) -> Instruction { | ||
| let commit_id_slice = self.commit_id.to_le_bytes(); | ||
| let (commit_buffer_pubkey, _) = | ||
| magicblock_committor_program::pdas::buffer_pda( | ||
| validator, | ||
| &self.committed_account.pubkey, | ||
| &commit_id_slice, | ||
| ); | ||
|
|
||
| dlp::instruction_builder::commit_diff_from_buffer( | ||
| *validator, | ||
| self.committed_account.pubkey, | ||
| self.committed_account.account.owner, | ||
| commit_buffer_pubkey, | ||
| CommitStateFromBufferArgs { | ||
| nonce: self.commit_id, | ||
| lamports: self.committed_account.account.lamports, | ||
| allow_undelegation: self.allow_undelegation, | ||
| }, | ||
| ) | ||
| } | ||
|
Comment on lines
+270
to
+294
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Clarify or remove the unused The If the parameter is truly unnecessary, apply this diff: fn create_commit_diff_from_buffer_ix(
&self,
validator: &Pubkey,
- _fetched_account: &Account,
) -> Instruction {Or add a comment if it's kept for consistency: fn create_commit_diff_from_buffer_ix(
&self,
validator: &Pubkey,
+ // Kept for API symmetry with create_commit_diff_ix, though unused
+ // since diff is read from buffer
_fetched_account: &Account,
) -> Instruction { |
||
| } | ||
|
|
||
| #[derive(Clone)] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -57,8 +57,8 @@ magicblock-config = { path = "../magicblock-config" } | |
| magicblock-core = { path = "../magicblock-core" } | ||
| magic-domain-program = { git = "https://github.com/magicblock-labs/magic-domain-program.git", rev = "ea04d46", default-features = false } | ||
| magicblock_magic_program_api = { package = "magicblock-magic-program-api", path = "../magicblock-magic-program-api" } | ||
| magicblock-delegation-program = { git = "https://github.com/magicblock-labs/delegation-program.git", rev = "e8d03936", features = [ | ||
| "no-entrypoint", | ||
| magicblock-delegation-program = { git = "https://github.com/magicblock-labs/delegation-program.git", rev = "ea1f2f916268132248fe8d5de5f07d76765dd937", features = [ | ||
| "no-entrypoint", | ||
| ] } | ||
|
Comment on lines
+60
to
62
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧹 Nitpick | 🔵 Trivial Consider using a branch reference instead of a commit hash for the magicblock-delegation-program dependency. While the delegation program is a professionally audited dependency with no identified security vulnerabilities, using a commit hash locks the dependency to a specific version. For consistency with repository best practices and to enable automatic updates when the repository is updated, switch to a branch reference (e.g., 🤖 Prompt for AI Agents |
||
| magicblock-program = { path = "../programs/magicblock" } | ||
| magicblock-rpc-client = { path = "../magicblock-rpc-client" } | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🛠️ Refactor suggestion | 🟠 Major
BufferTask now writes diff-or-state into buffer; ensure CommitTask is always in Buffer strategy when used here
Using
commit_task.compute_diff()to decide whether to write a diff or full state intoPreparationTask.committed_data, and derivingChunksfrom that length, is the right behavior for committing via buffers: buffer contents and chunking will match what*_from_bufferinstructions expect.One subtle requirement, though, is that the embedded
CommitTaskmust havestrategy == TaskStrategy::Buffer; otherwiseinstruction()will still emit the args-based commit instruction and completely ignore the prepared buffer, wasting the prep work and potentially re‑hitting tx-size limits.Since
ArgsTask::optimizealready callsvalue.switch_to_buffer_strategy()before wrapping inBufferTaskType::Commit, this is satisfied for the main flow, but any other construction ofBufferTask::Commit(including the tests) currently relies on the caller remembering to switch strategies.Consider tightening this by either:
BufferTask::new_preparation_required(orpreparation_required) assert in debug builds that the innerCommitTaskhasTaskStrategy::Buffer, and/orswitch_to_buffer_strategy()call into theBufferTaskconstruction path so callers cannot accidentally pass an Args‑strategy commit task.That would make BufferTask semantics self-contained and prevent silent misuse.
Also applies to: 65-77
🤖 Prompt for AI Agents