shadow_drive_user_staking/instructions/
initialize_config.rs

1use crate::constants::*;
2use crate::errors::ErrorCodes;
3use anchor_lang::prelude::*;
4
5/// This is the function that handles the `initialize_config` ix
6pub fn handler(
7    ctx: Context<InitializeStorageConfig>,
8    uploader: Pubkey,
9    admin_2: Option<Pubkey>,
10    // admin_3: Option<Pubkey>,
11    // admin_4: Option<Pubkey>,
12) -> Result<()> {
13    msg!("Initializing StorageConfig");
14    {
15        let storage_config = &mut ctx.accounts.storage_config;
16
17        // Initial storage cost
18        storage_config.shades_per_gib = INITIAL_STORAGE_COST;
19
20        // Initial storage available
21        storage_config.storage_available = INITIAL_STORAGE_AVAILABLE;
22
23        // Populate admins. admin_1 is a program constant.
24        storage_config.admin_2 = admin_2.unwrap_or(ctx.accounts.admin_1.key());
25        // storage_config.admin_3 = admin_3.unwrap_or(ctx.accounts.admin_1.key());
26        // storage_config.admin_4 = admin_4.unwrap_or(ctx.accounts.admin_1.key());
27
28        // Store uploader pubkey
29        storage_config.uploader = uploader;
30
31        // Initialize mutable fee variables
32        storage_config.mutable_fee_start_epoch = None;
33        storage_config.shades_per_gib_per_epoch = 0;
34        storage_config.crank_bps = INITIAL_CRANK_FEE_BPS;
35
36        // Initialize account limits
37        storage_config.max_account_size = MAX_ACCOUNT_SIZE;
38        storage_config.min_account_size = MIN_ACCOUNT_SIZE;
39    }
40
41    Ok(())
42}
43
44#[derive(Accounts)]
45/// This `InitializeStorageConfig` context is used to initialize the account which stores Shadow Drive
46/// configuration data including storage costs, admin pubkeys.
47pub struct InitializeStorageConfig<'info> {
48    /// This account is a PDA that holds the SPL's staking and slashing policy.
49    /// This is the account that signs transactions on behalf of the program to
50    /// distribute staking rewards.
51    #[account(
52        init,
53        payer = admin_1,
54        seeds = [
55            "storage-config".as_bytes()
56        ],
57        space = std::mem::size_of::<StorageConfig>() + 4, // 4 extra for None --> Some(u32)
58        bump,
59    )]
60    pub storage_config: Box<Account<'info, StorageConfig>>,
61
62    /// This account is the SPL's staking policy admin.
63    /// Must be either freeze or mint authority
64    #[account(mut, address=crate::constants::admin1::ID)]
65    pub admin_1: Signer<'info>,
66
67    /// System Program
68    pub system_program: Program<'info, System>,
69
70    /// Rent Program
71    pub rent: Sysvar<'info, Rent>,
72}
73
74#[account]
75pub struct StorageConfig {
76    /// Storage costs in shades per GiB
77    pub shades_per_gib: u64,
78
79    /// Total storage available (or remaining)
80    pub storage_available: u128,
81
82    /// Pubkey of SHDW token account that holds storage fees/stake
83    pub token_account: Pubkey,
84
85    /// Optional Admin 2
86    pub admin_2: Pubkey,
87
88    // /// Optional Admin 3
89    // pub admin_3: Pubkey,
90
91    // /// Optional Admin 4
92    // pub admin_4: Pubkey,
93    /// Uploader key, used to sign off on successful storage + CSAM scan
94    pub uploader: Pubkey,
95
96    /// Epoch at which mutable_account_fees turned on
97    pub mutable_fee_start_epoch: Option<u32>,
98
99    /// Mutable fee rate
100    pub shades_per_gib_per_epoch: u64,
101
102    /// Basis points cranker gets from cranking
103    pub crank_bps: u16,
104
105    /// Maximum size of a storage account
106    pub max_account_size: u64,
107
108    /// Minimum size of a storage account
109    pub min_account_size: u64,
110}
111
112impl StorageConfig {
113    pub fn validate_storage(&self, storage: u64) -> Result<u64> {
114        if storage <= self.max_account_size && storage >= self.min_account_size {
115            Ok(storage)
116        } else if storage < self.min_account_size {
117            msg!("Tiny account, failing");
118            Err(ErrorCodes::AccountTooSmall.into())
119        } else {
120            msg!("Very large account, failing");
121            Err(ErrorCodes::ExceededStorageLimit.into())
122        }
123    }
124}