Skip to content

Commit dafc2e9

Browse files
Fix: Ephemeral Rollups Pinocchio SDK (#69)
* fix: pinocchio sdk * fix: linter & CI * feat: fix pinocchio delegation * chore: lint * chore: enable tests in CI * chore: cancel prev workflow if newer * chore: remove test * fix: undelegation callback * chore: simplify and refactor * chore: refactor
1 parent b90c711 commit dafc2e9

File tree

11 files changed

+234
-255
lines changed

11 files changed

+234
-255
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
pull_request:
77
branches:
88
- "main"
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
912
env:
1013
rust_version: 1.89.0
1114
node_version: 23
@@ -135,3 +138,4 @@ jobs:
135138
solana --version
136139
cargo build
137140
anchor build --no-idl
141+
# anchor test

.github/workflows/publish-crates-and-sdk.yml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ on:
66
branches:
77
- 'release/v*'
88
workflow_dispatch:
9+
concurrency:
10+
group: ${{ github.workflow }}-${{ github.ref }}
11+
cancel-in-progress: true
912

1013
env:
1114
rust_version: 1.85.0

rust/Cargo.lock

Lines changed: 1 addition & 15 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

rust/Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,11 @@ solana-program = { version = ">=1.16" }
5555
sdk = { package = "solana-sdk", version = ">=1.16" }
5656
rpc = { package = "solana-rpc-client", version = ">=1.16" }
5757
rpc-api = { package = "solana-rpc-client-api", version = ">=1.16" }
58-
pinocchio = "0.8.1"
59-
pinocchio-log = "0.4.0"
60-
pinocchio-pubkey = "0.2.4"
61-
pinocchio-system = "0.2.3"
62-
pinocchio-token = "0.3.0"
58+
pinocchio = { version = "0.8.1", default-features = false }
59+
pinocchio-log = { version = "0.4.0", default-features = false }
60+
pinocchio-pubkey = { version = "0.2.4", default-features = false }
61+
pinocchio-system = { version = "0.2.3", default-features = false }
62+
pinocchio-token = { version = "0.3.0", default-features = false }
6363

6464
# serialization/parsing
6565
serde = { version = "1.0", features = [ "derive" ] }

rust/pinocchio/Cargo.toml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,9 @@ pinocchio-pubkey = { workspace = true }
1818
pinocchio-system = { workspace = true }
1919
pinocchio-token = { workspace = true }
2020

21+
[features]
22+
default = []
23+
std = [
24+
"pinocchio/std",
25+
]
26+
Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,32 @@
1-
use core::mem::MaybeUninit;
1+
use alloc::vec::Vec;
22
use pinocchio::{
33
account_info::AccountInfo,
44
cpi::{slice_invoke, MAX_CPI_ACCOUNTS},
5-
instruction::Instruction,
65
program_error::ProgramError,
76
ProgramResult,
87
};
98

109
use crate::utils::create_schedule_commit_ix;
1110

12-
pub fn commit_accounts(accounts: &[AccountInfo]) -> ProgramResult {
13-
let [payer, magic_context, magic_program, rest @ ..] = accounts else {
14-
return Err(ProgramError::NotEnoughAccountKeys);
15-
};
11+
pub fn commit_accounts(
12+
payer: &AccountInfo,
13+
accounts: &[AccountInfo],
14+
magic_context: &AccountInfo,
15+
magic_program: &AccountInfo,
16+
) -> ProgramResult {
17+
let ix = create_schedule_commit_ix(payer, accounts, magic_context, magic_program, false)?;
1618

17-
let (ix_data, ix_accounts) = create_schedule_commit_ix(payer, rest, magic_context, false)?;
18-
let ix = Instruction {
19-
program_id: magic_program.key(),
20-
data: ix_data,
21-
accounts: ix_accounts,
22-
};
23-
24-
let num_accounts = 2 + rest.len(); // payer + magic_context + rest
19+
let num_accounts = 1 + accounts.len(); // payer + accounts
2520
if num_accounts > MAX_CPI_ACCOUNTS {
2621
return Err(ProgramError::InvalidArgument);
2722
}
2823

29-
const UNINIT_REF: MaybeUninit<&AccountInfo> = MaybeUninit::<&AccountInfo>::uninit();
30-
let mut account_refs = [UNINIT_REF; MAX_CPI_ACCOUNTS];
31-
32-
unsafe {
33-
// SAFETY: num_accounts <= MAX_CPI_ACCOUNTS
34-
account_refs.get_unchecked_mut(0).write(payer);
35-
account_refs.get_unchecked_mut(1).write(magic_context);
36-
37-
// Add rest accounts
38-
for i in 0..rest.len() {
39-
let account = rest.get_unchecked(i);
40-
account_refs.get_unchecked_mut(2 + i).write(account);
41-
}
24+
let mut all_accounts: Vec<&AccountInfo> = Vec::with_capacity(accounts.len() + 1);
25+
all_accounts.push(payer);
26+
for account in accounts.iter() {
27+
all_accounts.push(account);
4228
}
4329

44-
let all_accounts = unsafe {
45-
core::slice::from_raw_parts(account_refs.as_ptr() as *const &AccountInfo, num_accounts)
46-
};
47-
48-
slice_invoke(&ix, all_accounts)?;
30+
slice_invoke(&ix, &all_accounts)?;
4931
Ok(())
5032
}
Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,32 @@
1-
use core::mem::MaybeUninit;
1+
use alloc::vec::Vec;
22
use pinocchio::{
33
account_info::AccountInfo,
44
cpi::{slice_invoke, MAX_CPI_ACCOUNTS},
5-
instruction::Instruction,
65
program_error::ProgramError,
76
ProgramResult,
87
};
98

109
use crate::utils::create_schedule_commit_ix;
1110

12-
pub fn commit_and_undelegate_accounts(accounts: &[AccountInfo]) -> ProgramResult {
13-
let [payer, magic_context, magic_program, rest @ ..] = accounts else {
14-
return Err(ProgramError::NotEnoughAccountKeys);
15-
};
11+
pub fn commit_and_undelegate_accounts(
12+
payer: &AccountInfo,
13+
accounts: &[AccountInfo],
14+
magic_context: &AccountInfo,
15+
magic_program: &AccountInfo,
16+
) -> ProgramResult {
17+
let ix = create_schedule_commit_ix(payer, accounts, magic_context, magic_program, true)?;
1618

17-
let (ix_data, ix_accounts) = create_schedule_commit_ix(payer, rest, magic_context, true)?;
18-
let ix = Instruction {
19-
program_id: magic_program.key(),
20-
data: ix_data,
21-
accounts: ix_accounts,
22-
};
23-
24-
let num_accounts = 2 + rest.len(); // payer + magic_context + rest
19+
let num_accounts = 1 + accounts.len(); // payer + accounts
2520
if num_accounts > MAX_CPI_ACCOUNTS {
2621
return Err(ProgramError::InvalidArgument);
2722
}
2823

29-
const UNINIT_REF: MaybeUninit<&AccountInfo> = MaybeUninit::<&AccountInfo>::uninit();
30-
let mut account_refs = [UNINIT_REF; MAX_CPI_ACCOUNTS];
31-
32-
unsafe {
33-
// SAFETY: num_accounts <= MAX_CPI_ACCOUNTS
34-
account_refs.get_unchecked_mut(0).write(payer);
35-
account_refs.get_unchecked_mut(1).write(magic_context);
36-
37-
// Add rest accounts
38-
for i in 0..rest.len() {
39-
let account = rest.get_unchecked(i);
40-
account_refs.get_unchecked_mut(2 + i).write(account);
41-
}
24+
let mut all_accounts: Vec<&AccountInfo> = Vec::with_capacity(accounts.len() + 1);
25+
all_accounts.push(payer);
26+
for account in accounts.iter() {
27+
all_accounts.push(account);
4228
}
4329

44-
let all_accounts = unsafe {
45-
core::slice::from_raw_parts(account_refs.as_ptr() as *const &AccountInfo, num_accounts)
46-
};
47-
48-
slice_invoke(&ix, all_accounts)?;
30+
slice_invoke(&ix, &all_accounts)?;
4931
Ok(())
5032
}

0 commit comments

Comments
 (0)