Skip to content

chore: upgrade solana and rust-toolchain#170

Open
snawaz wants to merge 8 commits intomainfrom
snawaz/upgrade
Open

chore: upgrade solana and rust-toolchain#170
snawaz wants to merge 8 commits intomainfrom
snawaz/upgrade

Conversation

@snawaz
Copy link
Copy Markdown
Contributor

@snawaz snawaz commented Apr 6, 2026

  • Zero functionality changes.
  • Upgrade Solana to 3.*.
  • Upgrade rust-toolchain to 1.94.1.
  • Upgrade other packages as well, needed to compile Solana 3.* with upgraded rust.

Summary by CodeRabbit

  • Chores
    • Rust toolchain bumped to 1.94.1.
    • Solana-related dependencies tightened to exact versions and new compatibility/interface crates added to improve reproducible builds.
  • Refactor
    • Centralized Solana API surface into a crate-level re-export and standardized imports across the codebase for cleaner maintenance.
  • Stability
    • No public API or runtime behavior changes for end users.

Copy link
Copy Markdown
Contributor Author

snawaz commented Apr 6, 2026

This stack of pull requests is managed by Graphite. Learn more about stacking.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Apr 6, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Added public re-export modules solana_program in both dlp-api/src/solana_program.rs and src/solana_program.rs, and updated codebase imports to use crate::solana_program::... instead of solana_program::.... Tightened Cargo dependency constraints by pinning Solana-related crates to exact versions and added solana-loader-v3-interface, solana-sdk-ids, and solana-system-interface. Updated macros and type paths to reference the crate-local reexports. Bumped Rust toolchain channel from 1.84.1 to 1.94.1. Removed impl From<DlpError> for pinocchio::error::ProgramError. Replaced some realloc(..., false) calls with resize(...). No other public API signatures were changed.

Suggested reviewers

  • GabrielePicco
  • taco-paco
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch snawaz/upgrade

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
dlp-api/src/instruction_builder/whitelist_validator_for_program.rs (1)

41-44: ⚠️ Potential issue | 🟠 Major

Remove panic path from instruction serialization.

Line 43 uses .unwrap(), which can panic in production. Please make this builder fallible and propagate serialization errors instead.

Proposed fix
-pub fn whitelist_validator_for_program(
+pub fn whitelist_validator_for_program(
     authority: Pubkey,
     validator_identity: Pubkey,
     program: Pubkey,
     insert: bool,
-) -> Instruction {
+) -> std::io::Result<Instruction> {
@@
-    Instruction {
+    Ok(Instruction {
         program_id: dlp::id(),
         accounts: vec![
@@
         data: [
             DlpDiscriminator::WhitelistValidatorForProgram.to_vec(),
-            to_vec(&args).unwrap(),
+            to_vec(&args)?,
         ]
         .concat(),
-    }
+    })
 }
As per coding guidelines: `Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.`
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/instruction_builder/whitelist_validator_for_program.rs` around
lines 41 - 44, The instruction builder currently calls to_vec(&args).unwrap()
(in the data array built with DlpDiscriminator::WhitelistValidatorForProgram)
which can panic; change the builder function (e.g., the function that constructs
the instruction bytes) to be fallible by returning Result<..., E> (choose an
appropriate error type such as anyhow::Error or a custom error/ProgramError),
replace the unwrap() with a fallible serialization call (e.g., let args_bytes =
to_vec(&args)?), propagate the error through the function signature, and update
callers to handle the Result accordingly so no panic path remains.
dlp-api/src/instruction_builder/validator_claim_fees.rs (1)

29-33: ⚠️ Potential issue | 🟠 Major

Replace .unwrap() with proper error handling.

The .unwrap() on to_vec(&args) violates the project's coding guidelines for production Rust code. While Borsh serialization of ValidatorClaimFeesArgs is unlikely to fail, the guidelines require explicit error handling or justification.

🔧 Proposed fix: Propagate the error

Option 1 - Change function signature to return Result:

 pub fn validator_claim_fees(
     validator: Pubkey,
     amount: Option<u64>,
-) -> Instruction {
+) -> Result<Instruction, std::io::Error> {
     let args = ValidatorClaimFeesArgs { amount };
     let fees_vault_pda = fees_vault_pda();
     let validator_fees_vault_pda =
         validator_fees_vault_pda_from_validator(&validator);
-    Instruction {
+    Ok(Instruction {
         program_id: dlp::id(),
         accounts: vec![
             AccountMeta::new(validator, true),
             AccountMeta::new(fees_vault_pda, false),
             AccountMeta::new(validator_fees_vault_pda, false),
         ],
         data: [
             DlpDiscriminator::ValidatorClaimFees.to_vec(),
-            to_vec(&args).unwrap(),
+            to_vec(&args)?,
         ]
         .concat(),
-    }
+    })
 }

Option 2 - If panicking is acceptable, add invariant documentation:

         data: [
             DlpDiscriminator::ValidatorClaimFees.to_vec(),
-            to_vec(&args).unwrap(),
+            // SAFETY: ValidatorClaimFeesArgs contains only Option<u64> which
+            // always serializes successfully
+            to_vec(&args).expect("ValidatorClaimFeesArgs serialization cannot fail"),
         ]

As per coding guidelines: {dlp-api,src}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/instruction_builder/validator_claim_fees.rs` around lines 29 -
33, The code calls to_vec(&args).unwrap() inside the data construction for
DlpDiscriminator::ValidatorClaimFees which must not panic; update the
ValidatorClaimFeesArgs serialization to return a Result and propagate or handle
the error: replace the unwrap with proper error propagation (e.g., have the
enclosing function return Result and use to_vec(&args)? or map_err(...) to
convert the serialization error into the function's error type) so that
serialization failures are returned to the caller instead of panicking; ensure
the change touches the call site building data (the array with
DlpDiscriminator::ValidatorClaimFees.to_vec() and the to_vec(&args) element) and
adjusts the function signature to return Result if necessary.
dlp-api/src/instruction_builder/top_up_ephemeral_balance.rs (1)

34-38: ⚠️ Potential issue | 🟠 Major

Replace .unwrap() with proper error handling.

The .unwrap() on to_vec(&args) violates the project's coding guidelines for production Rust code. While Borsh serialization of this simple struct is unlikely to fail, the guidelines require explicit error handling or justification.

Consider returning a Result from this function or using .expect() with a clear invariant comment if panicking is intentional.

🔧 Proposed fix: Propagate the error

Option 1 - Change function signature to return Result:

-pub fn top_up_ephemeral_balance(
+pub fn top_up_ephemeral_balance(
     payer: Pubkey,
     pubkey: Pubkey,
     amount: Option<u64>,
     index: Option<u8>,
-) -> Instruction {
+) -> Result<Instruction, std::io::Error> {
     let args = TopUpEphemeralBalanceArgs {
         amount: amount.unwrap_or(10000),
         index: index.unwrap_or(0),
     };
     let ephemeral_balance_pda =
         ephemeral_balance_pda_from_payer(&pubkey, args.index);
-    Instruction {
+    Ok(Instruction {
         program_id: dlp::id(),
         accounts: vec![
             AccountMeta::new(payer, true),
             AccountMeta::new_readonly(pubkey, false),
             AccountMeta::new(ephemeral_balance_pda, false),
             AccountMeta::new_readonly(system_program::id(), false),
         ],
         data: [
             DlpDiscriminator::TopUpEphemeralBalance.to_vec(),
-            to_vec(&args).unwrap(),
+            to_vec(&args)?,
         ]
         .concat(),
-    }
+    })
 }

Option 2 - If panicking is acceptable, add invariant documentation:

         data: [
             DlpDiscriminator::TopUpEphemeralBalance.to_vec(),
-            to_vec(&args).unwrap(),
+            // SAFETY: TopUpEphemeralBalanceArgs is a simple struct with fixed-size
+            // fields (u64, u8) that always serializes successfully
+            to_vec(&args).expect("TopUpEphemeralBalanceArgs serialization cannot fail"),
         ]

As per coding guidelines: {dlp-api,src}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/instruction_builder/top_up_ephemeral_balance.rs` around lines 34
- 38, The code currently calls to_vec(&args).unwrap() when building the data for
DlpDiscriminator::TopUpEphemeralBalance; remove the unwrap and propagate
serialization failures instead by changing the enclosing function (e.g., the
builder or TopUpEphemeralBalance creation function) to return Result<...,
SomeErrorType> and return Err(...) when to_vec(&args) fails (or map the Borsh
error into your crate error type), ensuring the callsite concatenates the
resulting Vec on success; if you truly intend to panic, replace unwrap() with
expect("invariant: TopUpEphemeralBalance args always serialize because ...") and
document the invariant, but preferred fix is to propagate the error from
to_vec(&args) rather than unwrapping.
dlp-api/src/compact/instruction.rs (1)

13-33: ⚠️ Potential issue | 🟠 Major

Don’t let from_instruction panic on a bad compact index.

index_of is caller-provided, so the .expect(...) on Line 32 can still abort production code. Please propagate a domain error instead of panicking here.

💡 One way to make this fallible
-    pub fn from_instruction(
+    pub fn from_instruction(
         ix: crate::solana_program::instruction::Instruction,
         index_of: &mut impl FnMut(
             /*account_key*/ crate::solana_program::pubkey::Pubkey,
             /*signer*/ bool,
         ) -> u8,
-    ) -> Instruction {
-        Instruction {
+    ) -> Result<Instruction, crate::solana_program::program_error::ProgramError> {
+        Ok(Instruction {
             program_id: index_of(ix.program_id, false),

             accounts: ix
                 .accounts
                 .iter()
                 .map(|meta| {
                     compact::AccountMeta::try_new(
                         index_of(meta.pubkey, meta.is_signer),
                         meta.is_signer,
                         meta.is_writable,
                     )
-                    .expect("compact account index must fit in 6 bits")
+                    .map_err(|_| crate::error::DlpError::TooManyAccountKeys.into())
                 })
-                .collect(),
+                .collect::<Result<Vec<_>, _>>()?,

             data: ix.data,
-        }
+        })
     }
As per coding guidelines, `{dlp-api,src}/**`: Treat any usage of `.unwrap()` or `.expect()` in production Rust code as a MAJOR issue.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/compact/instruction.rs` around lines 13 - 33, from_instruction
currently panics via .expect(...) when compact::AccountMeta::try_new fails; make
it fallible by changing from_instruction to return Result<Instruction, E>
(choose or add an appropriate domain error type, e.g., CompactIndexError or
reuse an existing crate error), replace the map+expect chain so you collect the
accounts with something like iter().map(...).collect::<Result<Vec<_>, _>>() and
propagate the try_new error into your Result, then construct and return
Instruction on Ok; update callers to handle the Result accordingly. Ensure you
reference the function from_instruction, the caller-provided index_of, and
compact::AccountMeta::try_new when implementing the change.
src/processor/utils/pda.rs (2)

114-121: ⚠️ Potential issue | 🟠 Major

Don’t panic while closing the PDA.

The .unwrap() on Line 117 still introduces a hard panic path in production code. Please return a normal program error here instead.

💡 Minimal fix
     **destination.lamports.borrow_mut() = dest_starting_lamports
         .checked_add(target_account.lamports())
-        .unwrap();
+        .ok_or(crate::error::DlpError::Overflow)?;
As per coding guidelines, `{dlp-api,src}/**`: Treat any usage of `.unwrap()` or `.expect()` in production Rust code as a MAJOR issue.

96-103: ⚠️ Potential issue | 🔴 Critical

Use the runtime rent sysvar and proper error handling in resize_pda and close_pda.

Two issues in the updated functions:

  1. resize_pda line 96: Rent::default() bakes in library defaults, so the top-up can drift from the cluster's actual rent schedule. Replace with Rent::get()? to match the pattern already used in create_pda.

  2. close_pda line 117: The .unwrap() on the checked_add will panic in production if lamport overflow occurs. Use proper error handling instead:

Minimal fixes
// resize_pda
-    let new_minimum_balance = Rent::default().minimum_balance(new_size);
+    let new_minimum_balance = Rent::get()?.minimum_balance(new_size);

// close_pda
-    **destination.lamports.borrow_mut() = dest_starting_lamports
-        .checked_add(target_account.lamports())
-        .unwrap();
+    **destination.lamports.borrow_mut() = dest_starting_lamports
+        .checked_add(target_account.lamports())
+        .ok_or(ProgramError::ArithmeticOverflow)?;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/processor/utils/pda.rs` around lines 96 - 103, In resize_pda, replace
Rent::default() with Rent::get()? so the top-up uses the runtime rent sysvar
(follow the same pattern as create_pda) and propagate the ?-error; in close_pda,
remove the unchecked .unwrap() on checked_add and handle the potential overflow
by returning an appropriate error (e.g., map None from checked_add to a custom
ProgramError or InvalidArgument) instead of panicking; update references in the
functions resize_pda and close_pda where
invoke(system_instruction::transfer(...)) and pda.lamports() are used to compute
lamports_diff so they use Rent::get()? and safe arithmetic via
checked_add/checked_sub with proper error returns.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dlp-api/src/state/utils/to_bytes.rs`:
- Around line 5-8: The exported macro generates methods like
to_bytes_with_discriminator(&self, data: &mut [u8]) -> Result<(),
crate::solana_program::program_error::ProgramError> which wrongly resolves
crate:: in the consumer crate; change the return type and any other uses of
crate::solana_program in the macro to use
$crate::solana_program::program_error::ProgramError (and analogous $crate::...
paths) so generated methods (e.g., to_bytes_with_discriminator and the other
methods at the referenced block 27-30) refer to the solana_program types inside
this crate via $crate::, matching the existing $crate::error usage.

In `@dlp-api/src/state/utils/try_from_bytes.rs`:
- Around line 5-7: The exported deserialization macros use
crate::solana_program::program_error::ProgramError in function return types
which resolves to the downstream crate; update the return types in the
macro-generated functions (e.g., pub fn try_from_bytes_with_discriminator, pub
fn try_from_bytes, and pub fn try_from_bytes_unchecked) to use
$crate::solana_program::program_error::ProgramError instead of crate::...,
matching the existing use of $crate::error::DlpError in the macro bodies so
downstream crates don't need a root-level solana_program module.

In `@src/entrypoint.rs`:
- Line 54: Replace the call to crate::solana_program::msg! in the entrypoint
error path with pinocchio_log::log! to follow project logging conventions:
change the invocation in the slow_process_instruction error/panic path (the line
using crate::solana_program::msg!("slow_process_instruction: {}", error)) to use
pinocchio_log::log! with the same message and error interpolation, and add the
necessary use/import for pinocchio_log::log if it isn't already present so the
symbol resolves.

In `@src/lib.rs`:
- Line 4: The declared local module "solana_program" (pub mod solana_program;)
has no backing file and causes compile errors; replace the local module
declaration with a re-export of the external wrapper (e.g., use pub use
dlp_api::solana_program;) so that existing crate::solana_program::* imports
resolve to the dlp_api wrapper instead of expecting a local src/solana_program
file.

---

Outside diff comments:
In `@dlp-api/src/compact/instruction.rs`:
- Around line 13-33: from_instruction currently panics via .expect(...) when
compact::AccountMeta::try_new fails; make it fallible by changing
from_instruction to return Result<Instruction, E> (choose or add an appropriate
domain error type, e.g., CompactIndexError or reuse an existing crate error),
replace the map+expect chain so you collect the accounts with something like
iter().map(...).collect::<Result<Vec<_>, _>>() and propagate the try_new error
into your Result, then construct and return Instruction on Ok; update callers to
handle the Result accordingly. Ensure you reference the function
from_instruction, the caller-provided index_of, and
compact::AccountMeta::try_new when implementing the change.

In `@dlp-api/src/instruction_builder/top_up_ephemeral_balance.rs`:
- Around line 34-38: The code currently calls to_vec(&args).unwrap() when
building the data for DlpDiscriminator::TopUpEphemeralBalance; remove the unwrap
and propagate serialization failures instead by changing the enclosing function
(e.g., the builder or TopUpEphemeralBalance creation function) to return
Result<..., SomeErrorType> and return Err(...) when to_vec(&args) fails (or map
the Borsh error into your crate error type), ensuring the callsite concatenates
the resulting Vec on success; if you truly intend to panic, replace unwrap()
with expect("invariant: TopUpEphemeralBalance args always serialize because
...") and document the invariant, but preferred fix is to propagate the error
from to_vec(&args) rather than unwrapping.

In `@dlp-api/src/instruction_builder/validator_claim_fees.rs`:
- Around line 29-33: The code calls to_vec(&args).unwrap() inside the data
construction for DlpDiscriminator::ValidatorClaimFees which must not panic;
update the ValidatorClaimFeesArgs serialization to return a Result and propagate
or handle the error: replace the unwrap with proper error propagation (e.g.,
have the enclosing function return Result and use to_vec(&args)? or map_err(...)
to convert the serialization error into the function's error type) so that
serialization failures are returned to the caller instead of panicking; ensure
the change touches the call site building data (the array with
DlpDiscriminator::ValidatorClaimFees.to_vec() and the to_vec(&args) element) and
adjusts the function signature to return Result if necessary.

In `@dlp-api/src/instruction_builder/whitelist_validator_for_program.rs`:
- Around line 41-44: The instruction builder currently calls
to_vec(&args).unwrap() (in the data array built with
DlpDiscriminator::WhitelistValidatorForProgram) which can panic; change the
builder function (e.g., the function that constructs the instruction bytes) to
be fallible by returning Result<..., E> (choose an appropriate error type such
as anyhow::Error or a custom error/ProgramError), replace the unwrap() with a
fallible serialization call (e.g., let args_bytes = to_vec(&args)?), propagate
the error through the function signature, and update callers to handle the
Result accordingly so no panic path remains.

In `@src/processor/utils/pda.rs`:
- Around line 96-103: In resize_pda, replace Rent::default() with Rent::get()?
so the top-up uses the runtime rent sysvar (follow the same pattern as
create_pda) and propagate the ?-error; in close_pda, remove the unchecked
.unwrap() on checked_add and handle the potential overflow by returning an
appropriate error (e.g., map None from checked_add to a custom ProgramError or
InvalidArgument) instead of panicking; update references in the functions
resize_pda and close_pda where invoke(system_instruction::transfer(...)) and
pda.lamports() are used to compute lamports_diff so they use Rent::get()? and
safe arithmetic via checked_add/checked_sub with proper error returns.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 95581f8a-6e2d-4d1d-9246-3996d789504f

📥 Commits

Reviewing files that changed from the base of the PR and between ec8ff51 and b4caf42.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (63)
  • Cargo.toml
  • dlp-api/Cargo.toml
  • dlp-api/src/args/delegate.rs
  • dlp-api/src/compact/instruction.rs
  • dlp-api/src/consts.rs
  • dlp-api/src/cpi/delegate_with_actions.rs
  • dlp-api/src/decrypt.rs
  • dlp-api/src/encrypt.rs
  • dlp-api/src/error.rs
  • dlp-api/src/instruction_builder/call_handler.rs
  • dlp-api/src/instruction_builder/call_handler_v2.rs
  • dlp-api/src/instruction_builder/close_ephemeral_balance.rs
  • dlp-api/src/instruction_builder/close_validator_fees_vault.rs
  • dlp-api/src/instruction_builder/commit_diff.rs
  • dlp-api/src/instruction_builder/commit_diff_from_buffer.rs
  • dlp-api/src/instruction_builder/commit_finalize.rs
  • dlp-api/src/instruction_builder/commit_finalize_from_buffer.rs
  • dlp-api/src/instruction_builder/commit_state.rs
  • dlp-api/src/instruction_builder/commit_state_from_buffer.rs
  • dlp-api/src/instruction_builder/delegate.rs
  • dlp-api/src/instruction_builder/delegate_ephemeral_balance.rs
  • dlp-api/src/instruction_builder/delegate_magic_fee_vault.rs
  • dlp-api/src/instruction_builder/delegate_with_actions.rs
  • dlp-api/src/instruction_builder/finalize.rs
  • dlp-api/src/instruction_builder/init_magic_fee_vault.rs
  • dlp-api/src/instruction_builder/init_protocol_fees_vault.rs
  • dlp-api/src/instruction_builder/init_validator_fees_vault.rs
  • dlp-api/src/instruction_builder/protocol_claim_fees.rs
  • dlp-api/src/instruction_builder/top_up_ephemeral_balance.rs
  • dlp-api/src/instruction_builder/types/encryptable_types.rs
  • dlp-api/src/instruction_builder/types/mod.rs
  • dlp-api/src/instruction_builder/undelegate.rs
  • dlp-api/src/instruction_builder/undelegate_confined_account.rs
  • dlp-api/src/instruction_builder/validator_claim_fees.rs
  • dlp-api/src/instruction_builder/whitelist_validator_for_program.rs
  • dlp-api/src/lib.rs
  • dlp-api/src/pda.rs
  • dlp-api/src/solana_program.rs
  • dlp-api/src/state/commit_record.rs
  • dlp-api/src/state/delegation_metadata.rs
  • dlp-api/src/state/delegation_record.rs
  • dlp-api/src/state/program_config.rs
  • dlp-api/src/state/utils/to_bytes.rs
  • dlp-api/src/state/utils/try_from_bytes.rs
  • rust-toolchain.toml
  • src/entrypoint.rs
  • src/lib.rs
  • src/processor/call_handler.rs
  • src/processor/call_handler_v2.rs
  • src/processor/close_ephemeral_balance.rs
  • src/processor/close_validator_fees_vault.rs
  • src/processor/delegate_ephemeral_balance.rs
  • src/processor/delegate_magic_fee_vault.rs
  • src/processor/fast/mod.rs
  • src/processor/init_magic_fee_vault.rs
  • src/processor/init_protocol_fees_vault.rs
  • src/processor/init_validator_fees_vault.rs
  • src/processor/protocol_claim_fees.rs
  • src/processor/top_up_ephemeral_balance.rs
  • src/processor/utils/loaders.rs
  • src/processor/utils/pda.rs
  • src/processor/validator_claim_fees.rs
  • src/processor/whitelist_validator_for_program.rs

@snawaz snawaz changed the title chore: upgrade solana chore: upgrade solana and rust-toolchain Apr 6, 2026
@snawaz snawaz marked this pull request as ready for review April 6, 2026 06:34
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (6)
dlp-api/src/instruction_builder/delegate_with_actions.rs (2)

29-34: ⚠️ Potential issue | 🟠 Major

Replace .expect() calls with proper error handling.

These .expect() calls will panic on failure without returning a Result to the caller. As per coding guidelines: "Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue."

Consider returning a Result from this function to allow callers to handle errors gracefully:

🛡️ Suggested approach
pub fn delegate_with_actions(
    payer: Pubkey,
    delegated_account: Pubkey,
    owner: Option<Pubkey>,
    delegate: DelegateArgs,
    actions: Vec<PostDelegationInstruction>,
) -> Result<Instruction, DelegateWithActionsError> {
    let encrypt_key = delegate
        .validator
        .ok_or(DelegateWithActionsError::ValidatorRequired)?;
    let (actions, signers) = actions
        .encrypt(&encrypt_key)
        .map_err(DelegateWithActionsError::EncryptionFailed)?;
    // ...
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/instruction_builder/delegate_with_actions.rs` around lines 29 -
34, The function uses .expect() on delegate.validator and on actions.encrypt
which will panic; change delegate_with_actions to return Result<Instruction,
DelegateWithActionsError> (or appropriate error enum), replace
delegate.validator.expect(...) with
delegate.validator.ok_or(DelegateWithActionsError::ValidatorRequired)?, and
replace actions.encrypt(&encrypt_key).expect(...) with
actions.encrypt(&encrypt_key).map_err(DelegateWithActionsError::EncryptionFailed)?
so errors are propagated instead of panicking; update callers/tests accordingly
and add the DelegateWithActionsError variants (ValidatorRequired,
EncryptionFailed) if they don't exist.

71-71: ⚠️ Potential issue | 🟠 Major

Replace .unwrap() with proper error handling.

The to_vec(&args).unwrap() will panic if serialization fails. This violates the coding guideline against .unwrap() usage. If the function signature is updated to return Result, this can use the ? operator. As per coding guidelines: "Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/instruction_builder/delegate_with_actions.rs` at line 71, The
call data.extend_from_slice(&to_vec(&args).unwrap()) uses to_vec(&args).unwrap()
which can panic; replace the unwrap by handling the serialization error: call
to_vec(&args) and propagate the Err via the function's Result return (use ?), or
map the error into your function's error type (e.g., to_vec(&args).map_err(|e|
/*wrap*/)?), or explicitly match and return an Err; update the surrounding
function signature to return Result if it currently returns () so you can use
the ? operator. Ensure the symbol to_vec(&args) is handled and no
.unwrap()/.expect() remain.
dlp-api/src/instruction_builder/delegate_ephemeral_balance.rs (1)

37-38: ⚠️ Potential issue | 🟠 Major

Replace .unwrap() with proper error handling.

Using .unwrap() on to_vec(&args) violates the coding guideline. As per coding guidelines: "Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue."

Consider returning a Result from this function or using a fallible approach.

🛡️ Suggested approach

If the function should remain infallible for API compatibility, document the invariant that serialization cannot fail for valid DelegateEphemeralBalanceArgs. Otherwise, consider:

pub fn delegate_ephemeral_balance(
    payer: Pubkey,
    pubkey: Pubkey,
    args: DelegateEphemeralBalanceArgs,
) -> Result<Instruction, std::io::Error> {
    // ...
    let mut data = DlpDiscriminator::DelegateEphemeralBalance.to_vec();
    data.extend_from_slice(&to_vec(&args)?);
    // ...
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/instruction_builder/delegate_ephemeral_balance.rs` around lines
37 - 38, The code calls to_vec(&args).unwrap() which panics on serialization
failure; update the DelegateEphemeralBalance instruction builder (the function
that constructs the Instruction that uses
DlpDiscriminator::DelegateEphemeralBalance and calls to_vec(&args)) to use
fallible error handling: change the function signature to return a
Result<Instruction, E> (or another appropriate error type), propagate the
serialization error instead of unwrapping (use ? on to_vec(&args) or map_err to
convert the error), and adjust callers accordingly or document the invariant if
you intentionally keep it infallible; ensure the data extension uses the
propagated bytes rather than unwrapping.
src/processor/delegate_ephemeral_balance.rs (1)

103-104: ⚠️ Potential issue | 🟠 Major

Replace .unwrap() with proper error handling.

Using .unwrap() on borsh::to_vec in production processor code violates coding guidelines. A serialization failure would panic without a meaningful error message. As per coding guidelines: "Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue."

🛡️ Proposed fix
     let mut data = DlpDiscriminator::Delegate.to_vec();
-    data.extend_from_slice(&borsh::to_vec(&args.delegate_args).unwrap());
+    data.extend_from_slice(
+        &borsh::to_vec(&args.delegate_args)
+            .map_err(|_| ProgramError::BorshIoError("Failed to serialize delegate args".to_string()))?,
+    );
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/processor/delegate_ephemeral_balance.rs` around lines 103 - 104, The code
uses borsh::to_vec(&args.delegate_args).unwrap() which will panic on
serialization failure; replace the unwrap with proper error handling by calling
borsh::to_vec(&args.delegate_args) and mapping or propagating the Result into
the function's error type (e.g., using ? if the caller returns Result, or
.map_err(|e| your_error::SerializationFailed(format!("delegate_args borsh error:
{}", e))) to convert into the processor error), then extend data with the
produced Vec; target the expression that builds data
(DlpDiscriminator::Delegate, args.delegate_args, and the borsh::to_vec call) so
the code logs or returns a meaningful error instead of panicking.
dlp-api/src/instruction_builder/commit_diff.rs (1)

30-30: ⚠️ Potential issue | 🟠 Major

Replace .unwrap() on instruction serialization (Line 30).

to_vec(&commit_args).unwrap() can panic and violates the repo rule for production Rust. Please propagate serialization errors (or add explicit invariant-based handling).

Proposed fix
-pub fn commit_diff(
+pub fn commit_diff(
     validator: Pubkey,
     delegated_account: Pubkey,
     delegated_account_owner: Pubkey,
     commit_args: CommitDiffArgs,
-) -> Instruction {
-    let commit_args = to_vec(&commit_args).unwrap();
+) -> Result<Instruction, std::io::Error> {
+    let commit_args = to_vec(&commit_args)?;
@@
-    Instruction {
+    Ok(Instruction {
         program_id: dlp::id(),
         accounts: vec![
@@
         ],
         data: [DlpDiscriminator::CommitDiff.to_vec(), commit_args].concat(),
-    }
+    })
 }

As per coding guidelines {dlp-api,src}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue; request proper error handling or explicit justification with invariants.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/instruction_builder/commit_diff.rs` at line 30, The code
currently uses to_vec(&commit_args).unwrap(), which can panic; replace the
unwrap by propagating the serialization error (e.g., let commit_args =
to_vec(&commit_args)? or to_vec(&commit_args).map_err(|e| /* convert to your
crate error */ )?), and update the enclosing function (e.g., the function that
builds the instruction in commit_diff.rs) to return a Result so the ? operator
can be used, or explicitly map the error into your module's error type before
returning; ensure the variable commit_args keeps the serialized Vec<u8> on
success and that callers handle the propagated error.
dlp-api/src/instruction_builder/call_handler_v2.rs (1)

49-49: ⚠️ Potential issue | 🟠 Major

Remove .unwrap() from args serialization (Line 49).

to_vec(&args).unwrap() is panic-prone and non-compliant with the repo rule. Propagate serialization errors from this builder.

Proposed fix
-pub fn call_handler_v2(
+pub fn call_handler_v2(
     validator: Pubkey,
     destination_program: Pubkey,
     source_program: Pubkey,
     escrow_authority: Pubkey,
     other_accounts: Vec<AccountMeta>,
     args: CallHandlerArgs,
-) -> Instruction {
+) -> Result<Instruction, std::io::Error> {
@@
-    Instruction {
+    Ok(Instruction {
         program_id: dlp::id(),
         accounts,
         data: [
             DlpDiscriminator::CallHandlerV2.to_vec(),
-            to_vec(&args).unwrap(),
+            to_vec(&args)?,
         ]
         .concat(),
-    }
+    })
 }

As per coding guidelines {dlp-api,src}/**: Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue; request proper error handling or explicit justification with invariants.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/instruction_builder/call_handler_v2.rs` at line 49, The call site
uses to_vec(&args).unwrap(), which can panic; remove the unwrap and propagate
the serialization error instead by returning a Result from the builder method
that contains this code (or map the serde/bincode error into the crate's error
type). Replace to_vec(&args).unwrap() with a non-panicking expression (e.g., let
serialized = to_vec(&args)? or to_vec(&args).map_err(|e|
MyError::Serialization(e))?) and adjust the enclosing function (the builder
method that constructs the call payload) to return Result so callers can handle
the error; keep the original variable name args and the to_vec call so the
change is minimal and local.
♻️ Duplicate comments (3)
src/entrypoint.rs (1)

53-53: 🧹 Nitpick | 🔵 Trivial

Use pinocchio_log::log! for this entrypoint error log.

Line 53 logs an entrypoint error via msg!; this should stay on pinocchio_log::log! for consistency with project preference.

Suggested patch
-            crate::solana_program::msg!("slow_process_instruction: {}", error);
+            pinocchio_log::log!("slow_process_instruction: {}", error);

Based on learnings: In the delegation-program codebase, prefer using log! (from pinocchio_log) over msg! for error and panic scenarios in the entrypoint code, as per maintainer preference.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/entrypoint.rs` at line 53, Replace the use of crate::solana_program::msg!
in the entrypoint error log with pinocchio_log::log! to follow project logging
convention; locate the call
crate::solana_program::msg!("slow_process_instruction: {}", error) (the
entrypoint error log for slow_process_instruction) and change it to use
pinocchio_log::log! with the same message and error interpolation.
src/lib.rs (1)

4-4: ⚠️ Potential issue | 🔴 Critical

Potential compile blocker at Line 4: local module declaration requires a backing file.

pub mod solana_program; will fail unless src/solana_program.rs (or src/solana_program/mod.rs) exists. That would break all crate::solana_program::* imports introduced in this PR.

Read-only verification script
#!/bin/bash
set -euo pipefail

echo "== src/lib.rs (module declaration) =="
sed -n '1,24p' src/lib.rs

echo
echo "== Search for backing module files =="
fd -HI '^solana_program\.rs$' src
fd -HI '^mod\.rs$' src/solana_program 2>/dev/null || true

echo
echo "== Search for re-export alternative =="
rg -n 'pub\s+use\s+dlp_api::solana_program|pub\s+mod\s+solana_program' src/lib.rs

Expected result:

  • Either a backing module file exists under src/, or
  • src/lib.rs uses a re-export (e.g. pub use dlp_api::solana_program;) instead of a local module declaration.
Minimal fix if no backing file exists
-pub mod solana_program;
+pub use dlp_api::solana_program;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib.rs` at line 4, The module declaration pub mod solana_program; is
missing its backing file and will fail compilation; either add the module file
named solana_program.rs or a module directory with mod.rs implementing the
public items referenced by crate::solana_program::*, or replace the local
declaration with a re-export (e.g., pub use dlp_api::solana_program;) so the
crate::solana_program::* imports resolve; update whichever you choose to ensure
the symbols used elsewhere match the new source (function/module names in the
new solana_program.rs or the re-exported module).
dlp-api/src/state/utils/to_bytes.rs (1)

8-9: ⚠️ Potential issue | 🟠 Major

Use $crate:: instead of crate:: inside exported macros.

In #[macro_export] macros, crate:: resolves in the caller's crate, not in dlp-api. This causes the generated methods to depend on a solana_program module existing at the downstream crate root. The macro already correctly uses $crate::error for error types, so the return type should follow the same pattern.

🛠️ Proposed fix
             pub fn to_bytes_with_discriminator(
                 &self,
                 data: &mut [u8],
-            ) -> Result<(), crate::solana_program::program_error::ProgramError>
+            ) -> Result<(), $crate::solana_program::program_error::ProgramError>
             {
             pub fn to_bytes_with_discriminator<W: std::io::Write>(
                 &self,
                 writer: &mut W,
-            ) -> Result<(), crate::solana_program::program_error::ProgramError>
+            ) -> Result<(), $crate::solana_program::program_error::ProgramError>
             {

Also applies to: 31-32

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@dlp-api/src/state/utils/to_bytes.rs` around lines 8 - 9, The generated
methods inside the #[macro_export] macro in to_bytes.rs currently use
crate::solana_program::program_error::ProgramError in their return type; change
those to $crate::solana_program::program_error::ProgramError so the generated
code references the symbols from this crate rather than the caller's crate
(update all occurrences noted, including the return type in the method
signatures around the shown block and the similar occurrences at lines 31-32).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@dlp-api/src/error.rs`:
- Around line 5-6: The generated methods from define_uninitialized_ctx! in
requires.rs call .into() on DlpError expecting pinocchio::error::ProgramError
but only an impl exists for crate::solana_program::program_error::ProgramError;
fix by either adding impl From<DlpError> for pinocchio::error::ProgramError in
dlp-api/src/error.rs (implement conversions for each DlpError variant to the
corresponding pinocchio::error::ProgramError) or change the macro to call an
explicit converter function (e.g., add a to_pinocchio_program_error(&self) ->
pinocchio::error::ProgramError on DlpError and replace .into() uses in
define_uninitialized_ctx! with
DlpError::<variant>.to_pinocchio_program_error()), referencing DlpError and
define_uninitialized_ctx! to locate the changes.

---

Outside diff comments:
In `@dlp-api/src/instruction_builder/call_handler_v2.rs`:
- Line 49: The call site uses to_vec(&args).unwrap(), which can panic; remove
the unwrap and propagate the serialization error instead by returning a Result
from the builder method that contains this code (or map the serde/bincode error
into the crate's error type). Replace to_vec(&args).unwrap() with a
non-panicking expression (e.g., let serialized = to_vec(&args)? or
to_vec(&args).map_err(|e| MyError::Serialization(e))?) and adjust the enclosing
function (the builder method that constructs the call payload) to return Result
so callers can handle the error; keep the original variable name args and the
to_vec call so the change is minimal and local.

In `@dlp-api/src/instruction_builder/commit_diff.rs`:
- Line 30: The code currently uses to_vec(&commit_args).unwrap(), which can
panic; replace the unwrap by propagating the serialization error (e.g., let
commit_args = to_vec(&commit_args)? or to_vec(&commit_args).map_err(|e| /*
convert to your crate error */ )?), and update the enclosing function (e.g., the
function that builds the instruction in commit_diff.rs) to return a Result so
the ? operator can be used, or explicitly map the error into your module's error
type before returning; ensure the variable commit_args keeps the serialized
Vec<u8> on success and that callers handle the propagated error.

In `@dlp-api/src/instruction_builder/delegate_ephemeral_balance.rs`:
- Around line 37-38: The code calls to_vec(&args).unwrap() which panics on
serialization failure; update the DelegateEphemeralBalance instruction builder
(the function that constructs the Instruction that uses
DlpDiscriminator::DelegateEphemeralBalance and calls to_vec(&args)) to use
fallible error handling: change the function signature to return a
Result<Instruction, E> (or another appropriate error type), propagate the
serialization error instead of unwrapping (use ? on to_vec(&args) or map_err to
convert the error), and adjust callers accordingly or document the invariant if
you intentionally keep it infallible; ensure the data extension uses the
propagated bytes rather than unwrapping.

In `@dlp-api/src/instruction_builder/delegate_with_actions.rs`:
- Around line 29-34: The function uses .expect() on delegate.validator and on
actions.encrypt which will panic; change delegate_with_actions to return
Result<Instruction, DelegateWithActionsError> (or appropriate error enum),
replace delegate.validator.expect(...) with
delegate.validator.ok_or(DelegateWithActionsError::ValidatorRequired)?, and
replace actions.encrypt(&encrypt_key).expect(...) with
actions.encrypt(&encrypt_key).map_err(DelegateWithActionsError::EncryptionFailed)?
so errors are propagated instead of panicking; update callers/tests accordingly
and add the DelegateWithActionsError variants (ValidatorRequired,
EncryptionFailed) if they don't exist.
- Line 71: The call data.extend_from_slice(&to_vec(&args).unwrap()) uses
to_vec(&args).unwrap() which can panic; replace the unwrap by handling the
serialization error: call to_vec(&args) and propagate the Err via the function's
Result return (use ?), or map the error into your function's error type (e.g.,
to_vec(&args).map_err(|e| /*wrap*/)?), or explicitly match and return an Err;
update the surrounding function signature to return Result if it currently
returns () so you can use the ? operator. Ensure the symbol to_vec(&args) is
handled and no .unwrap()/.expect() remain.

In `@src/processor/delegate_ephemeral_balance.rs`:
- Around line 103-104: The code uses borsh::to_vec(&args.delegate_args).unwrap()
which will panic on serialization failure; replace the unwrap with proper error
handling by calling borsh::to_vec(&args.delegate_args) and mapping or
propagating the Result into the function's error type (e.g., using ? if the
caller returns Result, or .map_err(|e|
your_error::SerializationFailed(format!("delegate_args borsh error: {}", e))) to
convert into the processor error), then extend data with the produced Vec;
target the expression that builds data (DlpDiscriminator::Delegate,
args.delegate_args, and the borsh::to_vec call) so the code logs or returns a
meaningful error instead of panicking.

---

Duplicate comments:
In `@dlp-api/src/state/utils/to_bytes.rs`:
- Around line 8-9: The generated methods inside the #[macro_export] macro in
to_bytes.rs currently use crate::solana_program::program_error::ProgramError in
their return type; change those to
$crate::solana_program::program_error::ProgramError so the generated code
references the symbols from this crate rather than the caller's crate (update
all occurrences noted, including the return type in the method signatures around
the shown block and the similar occurrences at lines 31-32).

In `@src/entrypoint.rs`:
- Line 53: Replace the use of crate::solana_program::msg! in the entrypoint
error log with pinocchio_log::log! to follow project logging convention; locate
the call crate::solana_program::msg!("slow_process_instruction: {}", error) (the
entrypoint error log for slow_process_instruction) and change it to use
pinocchio_log::log! with the same message and error interpolation.

In `@src/lib.rs`:
- Line 4: The module declaration pub mod solana_program; is missing its backing
file and will fail compilation; either add the module file named
solana_program.rs or a module directory with mod.rs implementing the public
items referenced by crate::solana_program::*, or replace the local declaration
with a re-export (e.g., pub use dlp_api::solana_program;) so the
crate::solana_program::* imports resolve; update whichever you choose to ensure
the symbols used elsewhere match the new source (function/module names in the
new solana_program.rs or the re-exported module).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: f7e65f1b-4bfe-45f3-9570-500fb2ea3e85

📥 Commits

Reviewing files that changed from the base of the PR and between b4caf42 and a98c6e4.

📒 Files selected for processing (54)
  • dlp-api/src/args/delegate.rs
  • dlp-api/src/consts.rs
  • dlp-api/src/cpi/delegate_with_actions.rs
  • dlp-api/src/decrypt.rs
  • dlp-api/src/encrypt.rs
  • dlp-api/src/error.rs
  • dlp-api/src/instruction_builder/call_handler.rs
  • dlp-api/src/instruction_builder/call_handler_v2.rs
  • dlp-api/src/instruction_builder/close_ephemeral_balance.rs
  • dlp-api/src/instruction_builder/close_validator_fees_vault.rs
  • dlp-api/src/instruction_builder/commit_diff.rs
  • dlp-api/src/instruction_builder/commit_diff_from_buffer.rs
  • dlp-api/src/instruction_builder/commit_finalize.rs
  • dlp-api/src/instruction_builder/commit_finalize_from_buffer.rs
  • dlp-api/src/instruction_builder/commit_state.rs
  • dlp-api/src/instruction_builder/commit_state_from_buffer.rs
  • dlp-api/src/instruction_builder/delegate.rs
  • dlp-api/src/instruction_builder/delegate_ephemeral_balance.rs
  • dlp-api/src/instruction_builder/delegate_magic_fee_vault.rs
  • dlp-api/src/instruction_builder/delegate_with_actions.rs
  • dlp-api/src/instruction_builder/finalize.rs
  • dlp-api/src/instruction_builder/init_magic_fee_vault.rs
  • dlp-api/src/instruction_builder/init_protocol_fees_vault.rs
  • dlp-api/src/instruction_builder/init_validator_fees_vault.rs
  • dlp-api/src/instruction_builder/protocol_claim_fees.rs
  • dlp-api/src/instruction_builder/top_up_ephemeral_balance.rs
  • dlp-api/src/instruction_builder/types/encryptable_types.rs
  • dlp-api/src/instruction_builder/types/mod.rs
  • dlp-api/src/instruction_builder/undelegate.rs
  • dlp-api/src/instruction_builder/undelegate_confined_account.rs
  • dlp-api/src/instruction_builder/validator_claim_fees.rs
  • dlp-api/src/instruction_builder/whitelist_validator_for_program.rs
  • dlp-api/src/solana_program.rs
  • dlp-api/src/state/commit_record.rs
  • dlp-api/src/state/delegation_metadata.rs
  • dlp-api/src/state/delegation_record.rs
  • dlp-api/src/state/program_config.rs
  • dlp-api/src/state/utils/to_bytes.rs
  • src/entrypoint.rs
  • src/lib.rs
  • src/processor/call_handler.rs
  • src/processor/call_handler_v2.rs
  • src/processor/close_ephemeral_balance.rs
  • src/processor/close_validator_fees_vault.rs
  • src/processor/delegate_ephemeral_balance.rs
  • src/processor/delegate_magic_fee_vault.rs
  • src/processor/init_magic_fee_vault.rs
  • src/processor/init_protocol_fees_vault.rs
  • src/processor/init_validator_fees_vault.rs
  • src/processor/protocol_claim_fees.rs
  • src/processor/top_up_ephemeral_balance.rs
  • src/processor/utils/loaders.rs
  • src/processor/validator_claim_fees.rs
  • src/processor/whitelist_validator_for_program.rs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/solana_program.rs`:
- Around line 1-14: The two identical shim modules (the top-level re-export pub
use ::solana_program::{declare_id, *}; plus the nested modules
system_instruction, system_program, and bpf_loader_upgradeable) are duplicated
between crates; extract these into a single shared crate/module and re-export
them from each crate instead of duplicating. Create a shared module that
contains the pub use ::solana_program line and the three submodules
(system_instruction, system_program, bpf_loader_upgradeable) and update the
current files to replace their inline definitions with pub use of that shared
module so callers keep the same symbols (declare_id, system_instruction::*,
system_program::*, bpf_loader_upgradeable::*).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 2cd22f56-ce01-4669-9240-14bc5e167efb

📥 Commits

Reviewing files that changed from the base of the PR and between a98c6e4 and 200ce10.

📒 Files selected for processing (1)
  • src/solana_program.rs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/processor/fast/utils/pda.rs (1)

72-74: ⚠️ Potential issue | 🟠 Major

Use checked arithmetic when crediting lamports in close flows.

These balance updates use unchecked + on u64; overflow here can corrupt accounting. Please switch to checked_add and return an explicit program error on overflow in both close_pda and close_pda_with_fees.

Also applies to: 103-105, 108-110

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/processor/fast/utils/pda.rs` around lines 72 - 74, The destination/target
lamports updates in close_pda and close_pda_with_fees use unchecked u64
addition; replace uses of destination.lamports() + target_account.lamports()
with checked_add and handle the None case by returning an explicit program error
(e.g., Err(ProgramError::InvalidAccountData) or a domain-specific error) instead
of overflowing silently; update all similar sites (the other occurrences around
the destination.set_lamports / target_account.set_lamports pairs at the
referenced locations) so you compute new_balance =
destination.lamports().checked_add(target_account.lamports()).ok_or(<overflow
error>)?, then call destination.set_lamports(new_balance) and set
target_account.set_lamports(0).
src/processor/utils/pda.rs (1)

115-117: ⚠️ Potential issue | 🟠 Major

Replace unwrap() with explicit overflow handling in lamport close transfer.

Line 117 can panic and abort execution if checked_add returns None; this should return a program error instead.

Suggested fix
     let dest_starting_lamports = destination.lamports();
     **destination.lamports.borrow_mut() = dest_starting_lamports
         .checked_add(target_account.lamports())
-        .unwrap();
+        .ok_or(ProgramError::ArithmeticOverflow)?;

As per coding guidelines {dlp-api,src}/**: "Treat any usage of .unwrap() or .expect() in production Rust code as a MAJOR issue."

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/processor/utils/pda.rs` around lines 115 - 117, The addition using
checked_add on dest_starting_lamports and target_account.lamports() currently
calls .unwrap(), which can panic; instead handle the None case and return a
ProgramError from this function (e.g., map the None to a descriptive error such
as an arithmetic overflow or custom program error) so the lamports transfer
fails gracefully; update the code around destination.lamports.borrow_mut()
assignment (referencing dest_starting_lamports, target_account.lamports(), and
destination.lamports) to use checked_add(...).ok_or(...) or an equivalent match
and return an Err(...) rather than unwrapping.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/processor/fast/utils/pda.rs`:
- Around line 72-74: The destination/target lamports updates in close_pda and
close_pda_with_fees use unchecked u64 addition; replace uses of
destination.lamports() + target_account.lamports() with checked_add and handle
the None case by returning an explicit program error (e.g.,
Err(ProgramError::InvalidAccountData) or a domain-specific error) instead of
overflowing silently; update all similar sites (the other occurrences around the
destination.set_lamports / target_account.set_lamports pairs at the referenced
locations) so you compute new_balance =
destination.lamports().checked_add(target_account.lamports()).ok_or(<overflow
error>)?, then call destination.set_lamports(new_balance) and set
target_account.set_lamports(0).

In `@src/processor/utils/pda.rs`:
- Around line 115-117: The addition using checked_add on dest_starting_lamports
and target_account.lamports() currently calls .unwrap(), which can panic;
instead handle the None case and return a ProgramError from this function (e.g.,
map the None to a descriptive error such as an arithmetic overflow or custom
program error) so the lamports transfer fails gracefully; update the code around
destination.lamports.borrow_mut() assignment (referencing
dest_starting_lamports, target_account.lamports(), and destination.lamports) to
use checked_add(...).ok_or(...) or an equivalent match and return an Err(...)
rather than unwrapping.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6ddac4cc-8ae7-4f39-8e0b-2a785171232d

📥 Commits

Reviewing files that changed from the base of the PR and between 200ce10 and 3ea9846.

📒 Files selected for processing (5)
  • dlp-api/src/diff/algorithm.rs
  • dlp-api/src/state/utils/to_bytes.rs
  • dlp-api/src/state/utils/try_from_bytes.rs
  • src/processor/fast/utils/pda.rs
  • src/processor/utils/pda.rs

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/processor/utils/pda.rs (1)

1-5: 🧹 Nitpick | 🔵 Trivial

Minor inconsistency between imported invoke and fully qualified paths.

The import statement brings in program::invoke, but the code uses fully qualified crate::solana_program::program::invoke_signed and crate::solana_program::system_instruction::* at call sites (lines 25-26, 47-48, 61-62, 73-74). Meanwhile, line 98 uses the shorter invoke form via the import.

Consider either:

  • Using the imported shorter form consistently, or
  • Removing unused imports and using fully qualified paths everywhere

This is a minor style nit and doesn't affect correctness.

Also applies to: 25-26, 47-48, 61-62, 73-74, 98-99

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/processor/utils/pda.rs` around lines 1 - 5, The imports mix a short
`invoke` with fully-qualified call sites
(`crate::solana_program::program::invoke_signed` and
`crate::solana_program::system_instruction::*`), so make them consistent: either
remove the `program::invoke` import and replace the short `invoke` usage with
`crate::solana_program::program::invoke`/`invoke_signed` everywhere, or import
both `program::invoke_signed` and `system_instruction::*` (in addition to
`program::invoke`) and update call sites to use the short forms (`invoke`,
`invoke_signed`, `system_instruction::...`) — adjust the import line and all
occurrences of `invoke`, `invoke_signed`, and `system_instruction` in pda.rs to
match the chosen style.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/processor/utils/pda.rs`:
- Around line 1-5: The imports mix a short `invoke` with fully-qualified call
sites (`crate::solana_program::program::invoke_signed` and
`crate::solana_program::system_instruction::*`), so make them consistent: either
remove the `program::invoke` import and replace the short `invoke` usage with
`crate::solana_program::program::invoke`/`invoke_signed` everywhere, or import
both `program::invoke_signed` and `system_instruction::*` (in addition to
`program::invoke`) and update call sites to use the short forms (`invoke`,
`invoke_signed`, `system_instruction::...`) — adjust the import line and all
occurrences of `invoke`, `invoke_signed`, and `system_instruction` in pda.rs to
match the chosen style.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 95c9e4a3-bb9f-4ead-aaff-3580e3ab8e78

📥 Commits

Reviewing files that changed from the base of the PR and between 3ea9846 and 6ba1ce3.

📒 Files selected for processing (5)
  • dlp-api/src/diff/algorithm.rs
  • dlp-api/src/state/utils/to_bytes.rs
  • dlp-api/src/state/utils/try_from_bytes.rs
  • src/processor/fast/utils/pda.rs
  • src/processor/utils/pda.rs

@snawaz snawaz requested a review from bmuddha April 6, 2026 10:03
@snawaz snawaz mentioned this pull request Apr 6, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant