Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
8 changes: 8 additions & 0 deletions .github/workflows/test-examples.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,14 @@ jobs:
steps:
- uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '20'

- name: Enable Corepack
run: corepack enable

- name: Setup Rust
uses: actions-rs/toolchain@v1
with:
Expand Down
35 changes: 30 additions & 5 deletions pinocchio-counter/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,39 @@ name = "pinocchio-counter"
version = "0.1.0"
edition = "2021"

[features]
logging = []

[dependencies]
pinocchio = { version = "0.10", features = ["cpi", "alloc", "copy"] }
pinocchio = { version = "0.10.1", features = ["cpi", "copy"] }
pinocchio-log = { version = "0.5" }
pinocchio-pubkey = { version = "0.3", features = ["const"] }
pinocchio-system = { version = "0.5" }
pinocchio-token = { version = "0.5" }
ephemeral-rollups-pinocchio = { version = "0.8.0", features = ["address-find-program-address"] }
ephemeral-rollups-pinocchio = { version = "0.8.1" }

[target.'cfg(not(any(target_os = "solana", target_arch = "bpf")))'.dependencies]
solana-pubkey = { version = "4.0.0", features = ["curve25519"] }

[dev-dependencies]
solana-instruction = "3.0.0"
solana-program = "3.0.0"
solana-program-test = "=3.0.2"
solana-pubkey = "4.0.0"
solana-signer = "3.0.0"
solana-transaction = "3.0.1"
solana-system-interface = { version = "2.0.0", features = ["bincode"] }
Comment thread
GabrielePicco marked this conversation as resolved.

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

[[test]]
name = "delegate_counter"
path = "tests-rs/delegate_counter.rs"

[[test]]
name = "increase_counter"
path = "tests-rs/increase_counter.rs"

[[test]]
name = "initialize_counter"
path = "tests-rs/initialize_counter.rs"
10 changes: 5 additions & 5 deletions pinocchio-counter/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,13 @@ cargo build-sbf
## Instructions

### 0: InitializeCounter
Initialize a counter PDA to 0.
Initialize a counter PDA to 0. Payload: `bump` (u8).

### 1: IncreaseCounter
Increase the counter by a specified amount (8-byte u64 payload).
Increase the counter by a specified amount. Payload: `bump` (u8) + `increase_by` (u64).

### 2: Delegate
Delegate the counter account to the Ephemeral Rollups delegation program.
Delegate the counter account to the Ephemeral Rollups delegation program. Payload: `bump` (u8).
Comment thread
GabrielePicco marked this conversation as resolved.

### 3: CommitAndUndelegate
Commit changes and undelegate the counter account.
Expand All @@ -43,10 +43,10 @@ Commit changes and undelegate the counter account.
Commit changes to the base layer.

### 5: IncrementAndCommit
Increment counter and commit in one instruction.
Increment counter and commit in one instruction. Payload: `bump` (u8) + `increase_by` (u64).

### 6: IncrementAndUndelegate
Increment counter and undelegate in one instruction.
Increment counter and undelegate in one instruction. Payload: `bump` (u8) + `increase_by` (u64).

## Account Structure

Expand Down
3 changes: 2 additions & 1 deletion pinocchio-counter/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@
"@solana/web3.js": "^1.93.0",
"borsh": "^0.7.0",
"dotenv": "^16.0.0"
}
},
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
157 changes: 152 additions & 5 deletions pinocchio-counter/src/entrypoint.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,162 @@
use crate::processor;
use crate::processor::{
process_commit, process_commit_and_undelegate, process_delegate, process_increase_counter,
process_increment_commit, process_increment_undelegate, process_initialize_counter,
process_undelegation_callback,
};
use core::{mem::MaybeUninit, slice::from_raw_parts};
use pinocchio::{
account::AccountView, entrypoint, Address, ProgramResult,
entrypoint::deserialize, error::ProgramError, no_allocator, nostd_panic_handler, AccountView,
Address, ProgramResult, MAX_TX_ACCOUNTS, SUCCESS,
};

entrypoint!(process_instruction);
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
enum InstructionDiscriminator {
InitializeCounter,
IncreaseCounter,
Delegate,
CommitAndUndelegate,
Commit,
IncrementAndCommit,
IncrementAndUndelegate,
UndelegationCallback,
}

impl InstructionDiscriminator {
const INITIALIZE_COUNTER: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0];
const INCREASE_COUNTER: [u8; 8] = [1, 0, 0, 0, 0, 0, 0, 0];
const DELEGATE: [u8; 8] = [2, 0, 0, 0, 0, 0, 0, 0];
const COMMIT_AND_UNDELEGATE: [u8; 8] = [3, 0, 0, 0, 0, 0, 0, 0];
const COMMIT: [u8; 8] = [4, 0, 0, 0, 0, 0, 0, 0];
const INCREMENT_AND_COMMIT: [u8; 8] = [5, 0, 0, 0, 0, 0, 0, 0];
const INCREMENT_AND_UNDELEGATE: [u8; 8] = [6, 0, 0, 0, 0, 0, 0, 0];
const UNDELEGATION_CALLBACK: [u8; 8] = [196, 28, 41, 206, 48, 37, 51, 167];

fn from_bytes(bytes: [u8; 8]) -> Result<Self, ProgramError> {
match bytes {
Self::INITIALIZE_COUNTER => Ok(Self::InitializeCounter),
Self::INCREASE_COUNTER => Ok(Self::IncreaseCounter),
Self::DELEGATE => Ok(Self::Delegate),
Self::COMMIT_AND_UNDELEGATE => Ok(Self::CommitAndUndelegate),
Self::COMMIT => Ok(Self::Commit),
Self::INCREMENT_AND_COMMIT => Ok(Self::IncrementAndCommit),
Self::INCREMENT_AND_UNDELEGATE => Ok(Self::IncrementAndUndelegate),
Self::UNDELEGATION_CALLBACK => Ok(Self::UndelegationCallback),
_ => Err(ProgramError::InvalidInstructionData),
}
}
}

// Do not allocate memory.
no_allocator!();
// Use the no_std panic handler.
nostd_panic_handler!();

#[no_mangle]
#[allow(clippy::arithmetic_side_effects)]
pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 {
const UNINIT: MaybeUninit<AccountView> = MaybeUninit::<AccountView>::uninit();
let mut accounts = [UNINIT; { MAX_TX_ACCOUNTS }];

let (program_id, count, instruction_data) =
deserialize::<MAX_TX_ACCOUNTS>(input, &mut accounts);

match process_instruction(
program_id,
from_raw_parts(accounts.as_ptr() as _, count),
instruction_data,
) {
Ok(()) => SUCCESS,
Err(error) => error.into(),
}
}
Comment thread
GabrielePicco marked this conversation as resolved.

/// Log an error.
#[cold]
fn log_error(_error: &ProgramError) {
#[cfg(feature = "logging")]
pinocchio_log::log!("Program error");
}

/// Process an instruction.
#[inline(always)]
pub fn process_instruction(
program_id: &Address,
accounts: &[AccountView],
instruction_data: &[u8],
) -> ProgramResult {
processor::process_instruction(program_id, accounts, instruction_data)?;
Ok(())
let result = inner_process_instruction(program_id, accounts, instruction_data);
result.inspect_err(log_error)
}

/// Process an instruction.
#[inline(always)]
pub(crate) fn inner_process_instruction(
program_id: &Address,
accounts: &[AccountView],
instruction_data: &[u8],
) -> ProgramResult {
if instruction_data.len() < 8 {
return Err(ProgramError::InvalidInstructionData);
}

let discriminator: [u8; 8] = instruction_data[..8]
.try_into()
.map_err(|_| ProgramError::InvalidInstructionData)?;
let discriminator = InstructionDiscriminator::from_bytes(discriminator)?;
let payload = &instruction_data[8..];

match discriminator {
InstructionDiscriminator::InitializeCounter => {
let bump = read_u8(payload)?;
process_initialize_counter(program_id, accounts, bump)
}
InstructionDiscriminator::IncreaseCounter => {
let (bump, increase_by) = read_bump_and_u64(payload)?;
process_increase_counter(program_id, accounts, bump, increase_by)
}
InstructionDiscriminator::Delegate => {
let bump = read_u8(payload)?;
process_delegate(program_id, accounts, bump)
}
InstructionDiscriminator::CommitAndUndelegate => {
process_commit_and_undelegate(program_id, accounts)
}
InstructionDiscriminator::Commit => process_commit(program_id, accounts),
InstructionDiscriminator::IncrementAndCommit => {
let (bump, increase_by) = read_bump_and_u64(payload)?;
process_increment_commit(program_id, accounts, bump, increase_by)
}
InstructionDiscriminator::IncrementAndUndelegate => {
let (bump, increase_by) = read_bump_and_u64(payload)?;
process_increment_undelegate(program_id, accounts, bump, increase_by)
}
InstructionDiscriminator::UndelegationCallback => {
process_undelegation_callback(program_id, accounts, payload)
}
}
}

fn read_u64(input: &[u8]) -> Result<u64, ProgramError> {
if input.len() < 8 {
return Err(ProgramError::InvalidInstructionData);
}
let mut bytes = [0u8; 8];
bytes.copy_from_slice(&input[..8]);
Ok(u64::from_le_bytes(bytes))
}

fn read_u8(input: &[u8]) -> Result<u8, ProgramError> {
if input.is_empty() {
return Err(ProgramError::InvalidInstructionData);
}
Ok(input[0])
}

fn read_bump_and_u64(input: &[u8]) -> Result<(u8, u64), ProgramError> {
if input.len() < 9 {
return Err(ProgramError::InvalidInstructionData);
}
let bump = read_u8(input)?;
let value = read_u64(&input[1..])?;
Ok((bump, value))
}
63 changes: 0 additions & 63 deletions pinocchio-counter/src/instruction.rs

This file was deleted.

12 changes: 8 additions & 4 deletions pinocchio-counter/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
pub mod entrypoint;
pub mod instruction;
pub mod processor;
pub mod state;
#![no_std]
#![allow(unexpected_cfgs)]

mod entrypoint;
mod processor;
mod state;

pub use crate::entrypoint::process_instruction;
Loading
Loading