-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlib.rs
94 lines (79 loc) · 3.63 KB
/
lib.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
use borsh::{BorshSerialize, BorshDeserialize};
use solana_program::{declare_id, msg, entrypoint::ProgramResult, account_info::{AccountInfo, next_account_info}, pubkey::Pubkey, borsh::try_from_slice_unchecked, program_error::ProgramError};
use solana_program::entrypoint;
declare_id!("RektC1oud1111111111111111111111111111111112");
#[derive(BorshSerialize, BorshDeserialize)]
pub enum Action {
Initialize,
Write { offset: u64, data: Vec<u8> },
Resize { size: u64 },
}
#[derive(BorshSerialize, BorshDeserialize)]
pub struct Update {
pub actions: Vec<Action>,
}
entrypoint!(process_instruction);
pub fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
msg!("Welcome to Rekt cloud");
msg!("{:?}", accounts);
let accounts_iter = &mut accounts.iter();
let authority = next_account_info(accounts_iter)?;
if !authority.is_signer {
return Err(ProgramError::IncorrectProgramId);
}
let update: Update = try_from_slice_unchecked(instruction_data)?;
for action in update.actions {
let storage = next_account_info(accounts_iter)?;
if storage.owner != program_id {
msg!("Storage account does not have the correct program id");
return Err(ProgramError::IncorrectProgramId);
}
match action {
Action::Initialize => {
msg!("Initializing {}...", storage.key);
let storage_authority = Pubkey::new(&storage.data.borrow()[0..32]);
if storage_authority != Pubkey::default() {
msg!("Storage account authority is already set");
return Err(ProgramError::InvalidAccountData);
}
// Write authority pubkey
let mut storage_data = storage.data.borrow_mut();
storage_data[0..32].copy_from_slice(&authority.key.to_bytes());
}
Action::Write { offset, data } => {
msg!("Writing to {}...", storage.key);
let storage_authority = Pubkey::new(&storage.data.borrow()[0..32]);
if &storage_authority != authority.key {
msg!("Storage account authority is {} not {}", storage_authority, authority.key);
return Err(ProgramError::InvalidAccountData);
}
// Check that offset >= 32 and that the write is within the storage account data size
if offset < 32 {
msg!("Offset would overwrite authority");
return Err(ProgramError::InvalidInstructionData);
}
if offset as usize + data.len() > storage.data_len() {
msg!("Writing after end of data len");
return Err(ProgramError::InvalidInstructionData);
}
msg!("Writing at {}, original data: {:?}", offset, &storage.data.borrow()[offset as usize..offset as usize + data.len()]);
storage.data.borrow_mut()[offset as usize..offset as usize + data.len()].copy_from_slice(&data);
}
Action::Resize { size } => {
msg!("Resizing {}...", storage.key);
let storage_authority = Pubkey::new(&storage.data.borrow()[0..32]);
if &storage_authority != authority.key {
msg!("Storage account authority is {} not {}", storage_authority, authority.key);
return Err(ProgramError::InvalidAccountData);
}
storage.realloc(size as usize, false)?;
}
}
}
msg!("See you later!");
Ok(())
}