use {
crate::state::*,
anchor_lang::prelude::*,
hpl_utils::{reallocate, Default},
std::cmp::max,
};
pub fn insert_public_info<'info>(
label: String,
value: String,
public_info: &mut Account<'info, PublicInfo>,
authority: &Signer<'info>,
rent_sysvar: &Sysvar<'info, Rent>,
system_program: &Program<'info, System>,
) -> Result<()> {
if let Some(old) = public_info.info.get(&label) {
let mut old_value_size: isize = 0;
println!("{}", old_value_size);
match old {
Info::SingleValue { value } => {
old_value_size = value.as_bytes().len() as isize;
}
}
let new_value_size = value.as_bytes().len() as isize;
let delta = new_value_size - old_value_size;
if delta != 0 {
reallocate(
delta,
public_info.to_account_info(),
authority.to_account_info(),
&rent_sysvar,
&system_program,
)?;
}
} else {
reallocate(
max(24, value.as_bytes().len() * 2) as isize
+ max(24, label.as_bytes().len() * 2) as isize,
public_info.to_account_info(),
authority.to_account_info(),
&rent_sysvar,
&system_program,
)?;
}
public_info
.info
.insert(label, Info::SingleValue { value: value });
Ok(())
}
#[derive(Accounts)]
#[instruction(_env: String)]
pub struct InitPublicInfo<'info> {
#[account(
init, payer = authority,
space = PublicInfo::LEN,
seeds = [b"public_info".as_ref(), _env.as_bytes(), crate::id().as_ref()],
bump,
)]
pub public_info: Account<'info, PublicInfo>,
#[account(mut)]
pub authority: Signer<'info>,
#[account()]
pub program_data: AccountInfo<'info>,
#[account(address = crate::id())]
pub program: AccountInfo<'info>,
pub system_program: Program<'info, System>,
}
pub fn init_public_info(ctx: Context<InitPublicInfo>, _env: String) -> Result<()> {
let public_info = &mut ctx.accounts.public_info;
public_info.set_defaults();
public_info.bump = ctx.bumps["public_info"];
Ok(())
}
#[derive(Accounts)]
#[instruction(_env: String)]
pub struct SetPublicInfo<'info> {
#[account(
mut,
seeds = [b"public_info".as_ref(), _env.as_bytes(), crate::id().as_ref()],
bump = public_info.bump,
)]
pub public_info: Account<'info, PublicInfo>,
#[account(mut)]
pub authority: Signer<'info>,
#[account()]
pub program_data: AccountInfo<'info>,
#[account(address = crate::id())]
pub program: AccountInfo<'info>,
pub rent_sysvar: Sysvar<'info, Rent>,
pub system_program: Program<'info, System>,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq)]
pub struct SetPublicInfoArgs {
pub label: String,
pub value: String,
}
pub fn set_public_info(
ctx: Context<SetPublicInfo>,
_env: String,
args: SetPublicInfoArgs,
) -> Result<()> {
let public_info = &mut ctx.accounts.public_info;
insert_public_info(
args.label,
args.value,
public_info,
&ctx.accounts.authority,
&ctx.accounts.rent_sysvar,
&ctx.accounts.system_program,
)?;
Ok(())
}
#[derive(Accounts)]
#[instruction(_env: String)]
pub struct SetAuthDriver<'info> {
#[account(
mut,
seeds = [b"public_info".as_ref(), _env.as_bytes(), crate::id().as_ref()],
bump = public_info.bump,
)]
pub public_info: Account<'info, PublicInfo>,
#[account()]
pub auth_driver: Signer<'info>,
#[account(mut)]
pub authority: Signer<'info>,
#[account()]
pub program_data: AccountInfo<'info>,
#[account(address = crate::id())]
pub program: AccountInfo<'info>,
pub rent_sysvar: Sysvar<'info, Rent>,
pub system_program: Program<'info, System>,
}
#[derive(AnchorSerialize, AnchorDeserialize, Clone, Debug, PartialEq)]
pub struct SetAuthDriverArgs {
pub driver_offchain: String,
}
pub fn set_auth_driver(
ctx: Context<SetAuthDriver>,
_env: String,
args: SetAuthDriverArgs,
) -> Result<()> {
let public_info = &mut ctx.accounts.public_info;
insert_public_info(
"auth_driver_offchain".to_string(),
args.driver_offchain,
public_info,
&ctx.accounts.authority,
&ctx.accounts.rent_sysvar,
&ctx.accounts.system_program,
)?;
insert_public_info(
"auth_driver_key".to_string(),
ctx.accounts.auth_driver.key().to_string(),
public_info,
&ctx.accounts.authority,
&ctx.accounts.rent_sysvar,
&ctx.accounts.system_program,
)?;
Ok(())
}