Skip to content
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

added basics/realloc/steel #253

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions basics/realloc/steel/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
target
test-ledger
21 changes: 21 additions & 0 deletions basics/realloc/steel/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[workspace]
resolver = "2"
members = ["api", "program"]

[workspace.package]
version = "0.1.0"
edition = "2021"
license = "Apache-2.0"
homepage = ""
documentation = ""
repository = ""
readme = "./README.md"
keywords = ["solana"]

[workspace.dependencies]
realloc-api = { path = "./api", version = "0.1.0" }
bytemuck = "1.14"
num_enum = "0.7"
solana-program = "1.18"
steel = "2.0"
thiserror = "1.0"
18 changes: 18 additions & 0 deletions basics/realloc/steel/api/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
[package]
name = "realloc-api"
description = "API for interacting with the Realloc program"
version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
documentation.workspace = true
repository.workspace = true
readme.workspace = true
keywords.workspace = true

[dependencies]
bytemuck.workspace = true
num_enum.workspace = true
solana-program.workspace = true
steel.workspace = true
thiserror.workspace = true
10 changes: 10 additions & 0 deletions basics/realloc/steel/api/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use steel::*;

#[derive(Debug, Error, Clone, Copy, PartialEq, Eq, IntoPrimitive)]
#[repr(u32)]
pub enum ReallocError {
#[error("Invalid string length")]
InvalidStringLength = 0,
}

error!(ReallocError);
25 changes: 25 additions & 0 deletions basics/realloc/steel/api/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
use steel::*;

#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, TryFromPrimitive)]
pub enum ReallocInstruction {
Initialize = 0,
Update = 1,
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Initialize {
pub message: [u8; 1024],
pub len: [u8; 4], // Store as bytes like in escrow
}

#[repr(C)]
#[derive(Clone, Copy, Debug, Pod, Zeroable)]
pub struct Update {
pub message: [u8; 1024],
pub len: [u8; 4],
}

instruction!(ReallocInstruction, Initialize);
instruction!(ReallocInstruction, Update);
24 changes: 24 additions & 0 deletions basics/realloc/steel/api/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
pub mod error;
pub mod instruction;
pub mod state;
pub mod sdk;

pub mod prelude {
pub use crate::error::*;
pub use crate::instruction::*;
pub use crate::state::*;
pub use crate::sdk::*;
pub use solana_program::{
account_info::AccountInfo,
entrypoint::ProgramResult,
msg,
pubkey::Pubkey,
rent::Rent,
system_program,
};
}

use steel::*;

// TODO Set program id
declare_id!("z7msBPQHDJjTvdQRoEcKyENgXDhSRYeHieN1ZMTqo35");
46 changes: 46 additions & 0 deletions basics/realloc/steel/api/src/sdk.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
use steel::*;
use crate::prelude::*;

pub fn initialize(
payer: Pubkey,
message_account: Pubkey,
message: String,
) -> Instruction {
let mut message_bytes = [0u8; 1024];
message_bytes[..message.len()].copy_from_slice(message.as_bytes());

Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(payer, true),
AccountMeta::new(message_account, true),
AccountMeta::new_readonly(system_program::ID, false),
],
data: Initialize {
message: message_bytes,
len: (message.len() as u32).to_le_bytes(),
}.to_bytes(),
}
}

pub fn update(
payer: Pubkey,
message_account: Pubkey,
message: String,
) -> Instruction {
let mut message_bytes = [0u8; 1024];
message_bytes[..message.len()].copy_from_slice(message.as_bytes());

Instruction {
program_id: crate::ID,
accounts: vec![
AccountMeta::new(payer, true),
AccountMeta::new(message_account, false),
AccountMeta::new_readonly(system_program::ID, false),
],
data: Update {
message: message_bytes,
len: (message.len() as u32).to_le_bytes(),
}.to_bytes(),
}
}
17 changes: 17 additions & 0 deletions basics/realloc/steel/api/src/state/message.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
use steel::*;
use super::ReallocAccount;

#[repr(C)]
#[derive(Clone, Copy, Debug, PartialEq, Pod, Zeroable)]
pub struct Message {
pub message: [u8; 1024], // Max message size
pub len: u32, // Actual length of message
}

impl Message {
pub fn required_space(message_len: usize) -> usize {
std::mem::size_of::<Message>()
}
}

account!(ReallocAccount, Message);
10 changes: 10 additions & 0 deletions basics/realloc/steel/api/src/state/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use steel::*;
mod message;

#[repr(u8)]
#[derive(Clone, Copy, Debug, Eq, PartialEq, IntoPrimitive, TryFromPrimitive)]
pub enum ReallocAccount {
Message = 0,
}

pub use message::*;
14 changes: 14 additions & 0 deletions basics/realloc/steel/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"name": "realloc-example",
"version": "1.0.0",
"description": "realloc basic example with steel framework for solana",
"scripts": {
"test": "cargo test-sbf",
"build-and-test": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./tests/fixtures && pnpm test",
"build": "cargo build-sbf --manifest-path=./program/Cargo.toml --sbf-out-dir=./program/target/so",
"deploy": "solana program deploy ./program/target/so/rent_example_program.so"
},
"keywords": [],
"author": "Nithin",
"license": "ISC"
}
26 changes: 26 additions & 0 deletions basics/realloc/steel/program/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "realloc-program"
description = ""
version.workspace = true
edition.workspace = true
license.workspace = true
homepage.workspace = true
documentation.workspace = true
repository.workspace = true
readme.workspace = true
keywords.workspace = true

[lib]
crate-type = ["cdylib", "lib"]

[dependencies]
realloc-api.workspace = true
solana-program.workspace = true
steel.workspace = true

[dev-dependencies]
base64 = "0.21"
rand = "0.8.5"
solana-program-test = "1.18"
solana-sdk = "1.18"
tokio = { version = "1.35", features = ["full"] }
32 changes: 32 additions & 0 deletions basics/realloc/steel/program/src/initialize.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
use realloc_api::prelude::*;
use steel::*;

pub fn process_initialize(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {
let args = Initialize::try_from_bytes(data)?;
let len = u32::from_le_bytes(args.len);

let [payer_info, message_account_info, system_program] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};

payer_info.is_signer()?;
message_account_info.is_signer()?;

// Create the account
let space = Message::required_space(len as usize);

create_account::<Message>(
message_account_info,
system_program,
payer_info,
&realloc_api::ID,
&[],
)?;

// Initialize the message
let message = message_account_info.as_account_mut::<Message>(&realloc_api::ID)?;
message.message = args.message;
message.len = len;

Ok(())
}
29 changes: 29 additions & 0 deletions basics/realloc/steel/program/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
use realloc_api::prelude::*;
use steel::*;

mod initialize;
mod update;

use initialize::process_initialize;
use update::process_update;

pub fn process_instruction(
program_id: &Pubkey,
accounts: &[AccountInfo],
data: &[u8],
) -> ProgramResult {
let (ix, data) = parse_instruction::<ReallocInstruction>(
&realloc_api::ID,
program_id,
data
)?;

match ix {
ReallocInstruction::Initialize => process_initialize(accounts, data)?,
ReallocInstruction::Update => process_update(accounts, data)?,
}

Ok(())
}

entrypoint!(process_instruction);
20 changes: 20 additions & 0 deletions basics/realloc/steel/program/src/update.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
use realloc_api::prelude::*;
use steel::*;

pub fn process_update(accounts: &[AccountInfo], data: &[u8]) -> ProgramResult {
let args = Update::try_from_bytes(data)?;
let len = u32::from_le_bytes(args.len);

let [payer_info, message_account_info, system_program] = accounts else {
return Err(ProgramError::NotEnoughAccountKeys);
};

payer_info.is_signer()?;

// Update the message
let message = message_account_info.as_account_mut::<Message>(&realloc_api::ID)?;
message.message = args.message;
message.len = len;

Ok(())
}
Loading
Loading