Skip to content
Merged
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
115 changes: 115 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
resolver = "2"
members = [
"benchmark",
"programs/jiminy",
"programs/pinocchio",
"programs/solana-nostd-entrypoint",
"programs/solana-program"
Expand Down
35 changes: 22 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,28 +19,37 @@ Entrypoint implementation currently included in the benchmark:
- [`pinocchio`](https://github.com/anza-xyz/pinocchio)
- [`solana-nostd-entrypoint`](https://github.com/cavemanloverboy/solana-nostd-entrypoint)
- [`solana-program`](https://github.com/anza-xyz/agave/tree/master/sdk/program)
- [`jiminy`](https://github.com/igneous-labs/jiminy)

| Benchmark | `pinocchio` | `solana-nostd-entrypoint` | `solana-program` |
| ------------- | ------------ | ------------------------- | ----------------- |
| Benchmark | `pinocchio` | `solana-nostd-entrypoint` | `solana-program` | `jiminy` |
| ------------- | --------------- | ------------------------- | ----------------- | ------------ |
| _Entrypoint_ |
| Ping | 🟩 **14** | 🟩 **14** | 🟧 41 (+27) |
| Log | 🟩 **119** | 🟩 **119** | 🟧 146 (+27) |
| Account (1) | 🟩 **38** | 🟩 39 (+1) | 🟥 235 (+196) |
| Account (3) | 🟩 **66** | 🟩 69 (+3) | 🟥 541 (+475) |
| Account (5) | 🟩 **94** | 🟩 99 (+5) | 🟥 847 (+753) |
| Account (10) | 🟩 **164** | 🟩 174 (+10) | 🟥 1,612 (+1,448) |
| Account (20) | 🟩 **304** | 🟨 324 (+20) | 🟥 3,142 (+2,838) |
| Account (32) | 🟩 **472** | 🟨 504 (+32) | 🟥 4,978 (+4,506) |
| Account (64) | 🟩 **920** | 🟨 985 (+65) | 🟥 9,874 (+8,954) |
| Ping | 🟩 **14** | 🟩 **14** | 🟧 41 (+27) | 🟩 **14** |
| Log | 🟩 **119** | 🟩 **119** | 🟧 146 (+27) | 🟩 **119** |
| Account (1) | 🟩 38 (+2) | 🟩 39 (+3) | 🟥 235 (+199) | 🟩 **36** |
| Account (3) | 🟩 **66** | 🟩 69 (+3) | 🟥 541 (+475) | 🟩 **66** |
| Account (5) | 🟩 **94** | 🟩 99 (+5) | 🟥 847 (+751) | 🟩 96 (+2) |
| Account (10) | 🟩 **164** | 🟩 174 (+10) | 🟥 1,612 (+1,441) | 🟩 171 (+7) |
| Account (20) | 🟩 **304** | 🟨 324 (+20) | 🟥 3,142 (+2,821) | 🟨 321 (+17) |
| Account (32) | 🟩 **472** | 🟨 504 (+32) | 🟥 4,978 (+4,477) | 🟨 501 (+29) |
| Account (64) | 🟩 **920** | 🟨 985 (+65) | 🟥 9,874 (+8,893) | 🟨 981 (+61) |
| _CPI_ |
| CreateAccount | 🟩 **1,449** | 🟨 1,494 (+45) | 🟥 2,786 (+1,337) |
| Transfer | 🟩 **1,439** | 🟨 1,487 (+48) | 🟥 2,379 (+940) |
| CreateAccount | 🟨 1,449 (+142) | 🟨 1,494 (+187) | 🟥 2,786 (+1,479) | 🟩 **1,307** |
| Transfer | 🟨 1,439 (+140) | 🟨 1,487 (+180) | 🟥 2,379 (+1,080) | 🟩 **1,299** |

> [!IMPORTANT]
> Values correspond to compute units (CUs) consumed by the entrypoint. The delta in relation to the lowest consumption is shown in brackets.
>
> Solana CLI `v2.2.6` was used in the bench tests.

## Binary Sizes

The size of the compiled benchmark program for each entrypoint is shown below. The delta in relation to the smallest binary size is shown in brackets.

| Binary size (bytes) | `pinocchio` | `solana-nostd-entrypoint` | `solana-program` | `jiminy` |
| ------------------- | ------------------ | ------------------------- | ------------------- | -------- |
| | 🟥 10,736 (+7,240) | 🟥 17,720 (+14,224) | 🟥 64,688 (+61,192) | 🟩 3,496 |

## Benchmark

The benchmark uses a simple program with multiple instructions to measure the compute units (CUs) consumed by the entrypoint. Note that the intention is not to write the most efficient program, instead to reflect an "average" program implementation. The aim is to use the exactly same program implementation, replacing the entrypoint to determine the impact on the CUs consumed.
Expand Down
1 change: 1 addition & 0 deletions benchmark/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ name = "coyote"
path = "src/main.rs"

[dev-dependencies]
eisodos-jiminy = { path="../programs/jiminy" }
eisodos-pinocchio = { path="../programs/pinocchio" }
eisodos-solana-nostd-entrypoint = { path="../programs/solana-nostd-entrypoint" }
eisodos-solana-program = { path="../programs/solana-program" }
Expand Down
23 changes: 23 additions & 0 deletions benchmark/benches/jiminy.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#![feature(test)]

extern crate mollusk_svm;
extern crate mollusk_svm_bencher;
extern crate solana_account;
extern crate solana_instruction;
extern crate solana_pubkey;
extern crate test;

mod setup;
use setup::*;

#[cfg(test)]
mod jiminy {

use super::*;
use test::Bencher;

#[bench]
fn run(_bencher: &mut Bencher) {
runner::run(&eisodos_jiminy::ID.into(), "eisodos_jiminy");
}
}
25 changes: 25 additions & 0 deletions programs/jiminy/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
[package]
name = "eisodos-jiminy"
version = "0.0.0"
edition = "2021"
publish = false

[package.metadata.solana]
program-id = "Jim1ny1111111111111111111111111111111111111"

[lints.rust.unexpected_cfgs]
level = "warn"
check-cfg = [
'cfg(target_os, values("solana"))',
]

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

[dependencies]
const-crypto = { version = "^0.3", default-features = false }
jiminy-cpi = { git = "https://github.com/igneous-labs/jiminy", branch = "master" }
jiminy-entrypoint = { git = "https://github.com/igneous-labs/jiminy", branch = "master" }
jiminy-log = { git = "https://github.com/igneous-labs/jiminy", branch = "master" }
jiminy-syscall = { git = "https://github.com/igneous-labs/jiminy", branch = "master" }
jiminy-system-prog-interface = { git = "https://github.com/igneous-labs/jiminy", branch = "master" }
27 changes: 27 additions & 0 deletions programs/jiminy/src/entrypoint.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
use crate::{
instruction::Instruction,
processor::{
process_account, process_create_account, process_log, process_ping, process_transfer,
},
Accounts, ProgramResult, MAX_ACCOUNTS,
};
use jiminy_entrypoint::entrypoint;

entrypoint!(process_instruction, MAX_ACCOUNTS);

#[inline(always)]
pub fn process_instruction(
accounts: &mut Accounts,
instruction_data: &[u8],
_program_id: &[u8; 32],
) -> ProgramResult {
let instruction = Instruction::unpack(instruction_data)?;

match instruction {
Instruction::Ping => process_ping(),
Instruction::Log => process_log(),
Instruction::Account { expected } => process_account(accounts, expected),
Instruction::CreateAccount => process_create_account(accounts),
Instruction::Transfer => process_transfer(accounts),
}
}
37 changes: 37 additions & 0 deletions programs/jiminy/src/instruction.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
use jiminy_entrypoint::program_error::{BuiltInProgramError, ProgramError};

#[derive(Clone, Debug)]
#[rustfmt::skip]
pub enum Instruction {
Ping,
Log,
Account {
expected: u64,
},
CreateAccount,
Transfer,
}

impl Instruction {
/// Unpacks a byte buffer into a [Instruction](enum.Instruction.html).
#[inline(always)]
pub fn unpack(input: &[u8]) -> Result<Self, ProgramError> {
match input.split_first() {
// 0 - Ping
Some((&0, [])) => Ok(Instruction::Ping),
// 1 - Log
Some((&1, [])) => Ok(Instruction::Log),
// 2 - Account
Some((&2, remaining)) if remaining.len() == 8 => Ok(Instruction::Account {
expected: u64::from_le_bytes(remaining[0..8].try_into().unwrap()),
}),
// 3 - CreateAccount
Some((&3, [])) => Ok(Instruction::CreateAccount),
// 4 - Transfer
Some((&4, [])) => Ok(Instruction::Transfer),
_ => Err(ProgramError::from_builtin(
BuiltInProgramError::InvalidInstructionData,
)),
}
}
}
19 changes: 19 additions & 0 deletions programs/jiminy/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use jiminy_entrypoint::program_error::ProgramError;

pub mod entrypoint;
pub mod instruction;
pub mod processor;

type ProgramResult = Result<(), ProgramError>;

const MAX_ACCOUNTS: usize = 128;
// TODO: CPI takes up way too much stack space
const MAX_CPI_ACCOUNTS: usize = 36;

type Cpi = jiminy_cpi::Cpi<MAX_CPI_ACCOUNTS>;

type Accounts<'a> = jiminy_entrypoint::account::Accounts<'a, MAX_ACCOUNTS>;

const PROG_ID_STR: &str = "Jim1ny1111111111111111111111111111111111111";

pub const ID: [u8; 32] = const_crypto::bs58::decode_pubkey(PROG_ID_STR);
Loading