-
Notifications
You must be signed in to change notification settings - Fork 87
chore: LightProgramInterface program rent sponsor #2214
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: main
Are you sure you want to change the base?
Changes from all commits
a4a6c80
660c3c1
6f721a8
bf4c0b5
efaa1b3
e09fe5f
c66d34c
b2e8ff5
46c505e
8fd616c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -7,6 +7,7 @@ use borsh::{BorshDeserialize as AnchorDeserialize, BorshSerialize as AnchorSeria | |
| use light_sdk::interface::config::LightConfig; | ||
| use solana_instruction::{AccountMeta, Instruction}; | ||
| use solana_pubkey::Pubkey; | ||
| use solana_system_interface::instruction as system_instruction; | ||
|
|
||
| /// Default address tree v2 pubkey. | ||
| pub const ADDRESS_TREE_V2: Pubkey = | ||
|
|
@@ -20,18 +21,22 @@ pub const DEFAULT_INIT_WRITE_TOP_UP: u32 = 5_000; | |
| pub struct InitializeCompressionConfigAnchorData { | ||
| pub write_top_up: u32, | ||
| pub rent_sponsor: Pubkey, | ||
| pub rent_sponsor_bump: u8, | ||
| pub compression_authority: Pubkey, | ||
| pub rent_config: light_compressible::rent::RentConfig, | ||
| pub address_space: Vec<Pubkey>, | ||
| } | ||
|
|
||
| /// Builder for `initialize_compression_config` instruction with sensible defaults. | ||
| /// | ||
| /// Automatically includes a transfer instruction to fund the rent sponsor PDA. | ||
| pub struct InitializeRentFreeConfig { | ||
| program_id: Pubkey, | ||
| fee_payer: Pubkey, | ||
| program_data_pda: Pubkey, | ||
| authority: Option<Pubkey>, | ||
| rent_sponsor: Pubkey, | ||
| rent_sponsor_funding: u64, | ||
| compression_authority: Pubkey, | ||
| rent_config: light_compressible::rent::RentConfig, | ||
| write_top_up: u32, | ||
|
|
@@ -40,19 +45,26 @@ pub struct InitializeRentFreeConfig { | |
| } | ||
|
|
||
| impl InitializeRentFreeConfig { | ||
| /// Creates a new builder for initializing rent-free config. | ||
| /// | ||
| /// # Arguments | ||
| /// * `rent_sponsor_funding` - Lamports to transfer to the rent sponsor PDA. | ||
| /// This funds the PDA that will pay rent for compressed accounts. | ||
| pub fn new( | ||
| program_id: &Pubkey, | ||
| fee_payer: &Pubkey, | ||
| program_data_pda: &Pubkey, | ||
| rent_sponsor: Pubkey, | ||
| compression_authority: Pubkey, | ||
| rent_sponsor_funding: u64, | ||
| ) -> Self { | ||
| Self { | ||
| program_id: *program_id, | ||
| fee_payer: *fee_payer, | ||
| program_data_pda: *program_data_pda, | ||
| authority: None, | ||
| rent_sponsor, | ||
| rent_sponsor_funding, | ||
| compression_authority, | ||
| rent_config: light_compressible::rent::RentConfig::default(), | ||
| write_top_up: DEFAULT_INIT_WRITE_TOP_UP, | ||
|
|
@@ -86,10 +98,34 @@ impl InitializeRentFreeConfig { | |
| self | ||
| } | ||
|
|
||
| pub fn build(self) -> (Instruction, Pubkey) { | ||
| /// Builds the instructions to initialize rent-free config. | ||
| /// | ||
| /// Returns a vector containing: | ||
| /// 1. Transfer instruction to fund the rent sponsor PDA | ||
| /// 2. Initialize compression config instruction | ||
| /// | ||
| /// Both instructions should be sent in a single atomic transaction. | ||
| pub fn build(self) -> (Vec<Instruction>, Pubkey) { | ||
| let authority = self.authority.unwrap_or(self.fee_payer); | ||
| let (config_pda, _) = LightConfig::derive_pda(&self.program_id, self.config_bump); | ||
|
|
||
| // Derive rent sponsor bump (version 1, hardcoded) | ||
| let (derived_rent_sponsor, rent_sponsor_bump) = | ||
| Pubkey::find_program_address(&[b"rent_sponsor", &1u16.to_le_bytes()], &self.program_id); | ||
| assert_eq!( | ||
| derived_rent_sponsor, self.rent_sponsor, | ||
| "Rent sponsor PDA mismatch: derived {:?} != provided {:?}", | ||
| derived_rent_sponsor, self.rent_sponsor | ||
| ); | ||
|
Comment on lines
+112
to
+119
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 returning Using That said, the current implementation does catch misconfigurations early with a clear error message, so this is a design tradeoff rather than a bug. ♻️ Suggested approach- pub fn build(self) -> (Vec<Instruction>, Pubkey) {
+ pub fn build(self) -> Result<(Vec<Instruction>, Pubkey), InitConfigError> {
let authority = self.authority.unwrap_or(self.fee_payer);
let (config_pda, _) = LightConfig::derive_pda(&self.program_id, self.config_bump);
// Derive rent sponsor bump (version 1, hardcoded)
let (derived_rent_sponsor, rent_sponsor_bump) =
Pubkey::find_program_address(&[b"rent_sponsor", &1u16.to_le_bytes()], &self.program_id);
- assert_eq!(
- derived_rent_sponsor, self.rent_sponsor,
- "Rent sponsor PDA mismatch: derived {:?} != provided {:?}",
- derived_rent_sponsor, self.rent_sponsor
- );
+ if derived_rent_sponsor != self.rent_sponsor {
+ return Err(InitConfigError::RentSponsorMismatch {
+ derived: derived_rent_sponsor,
+ provided: self.rent_sponsor,
+ });
+ }🤖 Prompt for AI Agents |
||
|
|
||
| // 1. Transfer to fund rent sponsor PDA | ||
| let transfer_ix = system_instruction::transfer( | ||
| &self.fee_payer, | ||
| &self.rent_sponsor, | ||
| self.rent_sponsor_funding, | ||
| ); | ||
|
Comment on lines
+121
to
+126
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. 🧩 Analysis chain🏁 Script executed: # Find the InitializeRentFreeConfig struct definition and its constructor
rg -n "struct InitializeRentFreeConfig\|impl.*InitializeRentFreeConfig" --type rust -A 15 | head -100Repository: Lightprotocol/light-protocol Length of output: 54 🏁 Script executed: # Search for usages of InitializeRentFreeConfig::new
rg -n "InitializeRentFreeConfig\s*\{|InitializeRentFreeConfig::new" --type rust -B 2 -A 5 | head -150Repository: Lightprotocol/light-protocol Length of output: 12460 🏁 Script executed: # Find the initialize_config.rs file to examine the full context
fd "initialize_config.rs" --type fRepository: Lightprotocol/light-protocol Length of output: 122 🏁 Script executed: # Look for CLAUDE.md and rent-related documentation
fd "CLAUDE.md" --type f
fd -e md | grep -i "rent\|config" | head -20Repository: Lightprotocol/light-protocol Length of output: 837 🏁 Script executed: # Read the initialize_config.rs file to see the full implementation
cat -n sdk-libs/client/src/interface/initialize_config.rsRepository: Lightprotocol/light-protocol Length of output: 7342 🏁 Script executed: # Check the CLAUDE.md file at the root to understand rent sponsor semantics
cat -n CLAUDE.md | head -100Repository: Lightprotocol/light-protocol Length of output: 6365 🏁 Script executed: # Check the compressible CLAUDE.md for rent sponsor information
cat -n program-libs/compressible/CLAUDE.md | head -150Repository: Lightprotocol/light-protocol Length of output: 2496 🏁 Script executed: # Search for validation of rent_sponsor_funding across the codebase
rg "rent_sponsor_funding" --type rust -B 2 -A 2Repository: Lightprotocol/light-protocol Length of output: 2179 Add validation to prevent zero-amount transfer instruction. The code creates a transfer instruction without checking if 🤖 Prompt for AI Agents |
||
|
|
||
| // 2. Initialize compression config | ||
| let accounts = vec![ | ||
| AccountMeta::new(self.fee_payer, true), // payer | ||
| AccountMeta::new(config_pda, false), // config | ||
|
|
@@ -104,6 +140,7 @@ impl InitializeRentFreeConfig { | |
| let instruction_data = InitializeCompressionConfigAnchorData { | ||
| write_top_up: self.write_top_up, | ||
| rent_sponsor: self.rent_sponsor, | ||
| rent_sponsor_bump, | ||
| compression_authority: self.compression_authority, | ||
| rent_config: self.rent_config, | ||
| address_space: self.address_space, | ||
|
|
@@ -121,12 +158,12 @@ impl InitializeRentFreeConfig { | |
| data.extend_from_slice(&DISCRIMINATOR); | ||
| data.extend_from_slice(&serialized_data); | ||
|
|
||
| let instruction = Instruction { | ||
| let init_config_ix = Instruction { | ||
| program_id: self.program_id, | ||
| accounts, | ||
| data, | ||
| }; | ||
|
|
||
| (instruction, config_pda) | ||
| (vec![transfer_ix, init_config_ix], config_pda) | ||
| } | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.