-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Rust programs using
pinocchio
(#7)
* Add pinocchio programs * Bypass borrow check * Use lazy entrypoint * Update pinocchio results * Update crate version * Remove duplicated tests * Add pinocchio test script * Update CU values * Clean up * Add number of accounts assert * Simplify program name env
- Loading branch information
Showing
12 changed files
with
256 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,10 @@ | ||
[workspace] | ||
members = [ | ||
"cpi", | ||
"cpi/pinocchio", | ||
"helloworld", | ||
"transfer-lamports" | ||
"transfer-lamports", | ||
"transfer-lamports/pinocchio" | ||
] | ||
resolver = "2" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
[package] | ||
name = "pinocchio-rosetta-cpi" | ||
version = "1.0.0" | ||
edition = "2021" | ||
|
||
[dependencies] | ||
pinocchio = "0.6" | ||
pinocchio-system = "0.2" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "lib"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
//! Rust example using pinocchio demonstrating invoking another program | ||
#![deny(missing_docs)] | ||
|
||
use pinocchio::{ | ||
instruction::{Account, AccountMeta, Instruction}, | ||
lazy_entrypoint::InstructionContext, | ||
program::invoke_signed_unchecked, | ||
program_error::ProgramError, | ||
pubkey::create_program_address, | ||
signer, ProgramResult, | ||
}; | ||
|
||
// Since this is a single instruction program, we use the "lazy" variation | ||
// of the entrypoint. | ||
pinocchio::lazy_entrypoint!(process_instruction); | ||
|
||
/// Amount of bytes of account data to allocate | ||
pub const SIZE: usize = 42; | ||
|
||
/// Instruction processor. | ||
fn process_instruction(mut context: InstructionContext) -> ProgramResult { | ||
if context.remaining() != 2 { | ||
return Err(ProgramError::NotEnoughAccountKeys); | ||
} | ||
|
||
// Account info to allocate and for the program being invoked. We know that | ||
// we got 2 accounts, so it is ok use `next_account_unchecked` twice. | ||
let allocated_info = unsafe { context.next_account_unchecked().assume_account() }; | ||
// just move the offset, we don't need the system program info | ||
let _system_program_info = unsafe { context.next_account_unchecked() }; | ||
|
||
// Again, don't need to check that all accounts have been consumed, we know | ||
// we have exactly 2 accounts. | ||
let (instruction_data, program_id) = unsafe { context.instruction_data_unchecked() }; | ||
|
||
let expected_allocated_key = | ||
create_program_address(&[b"You pass butter", &[instruction_data[0]]], program_id)?; | ||
if *allocated_info.key() != expected_allocated_key { | ||
// allocated key does not match the derived address | ||
return Err(ProgramError::InvalidArgument); | ||
} | ||
|
||
// Invoke the system program to allocate account data | ||
let mut data = [0; 12]; | ||
data[0] = 8; // ix discriminator | ||
data[4..12].copy_from_slice(&SIZE.to_le_bytes()); | ||
|
||
let instruction = Instruction { | ||
program_id: &pinocchio_system::ID, | ||
accounts: &[AccountMeta::writable_signer(allocated_info.key())], | ||
data: &data, | ||
}; | ||
|
||
// Invoke the system program with the 'unchecked' function - this is ok since | ||
// we know the accounts are not borrowed elsewhere. | ||
unsafe { | ||
invoke_signed_unchecked( | ||
&instruction, | ||
&[Account::from(&allocated_info)], | ||
&[signer!(b"You pass butter", &[instruction_data[0]])], | ||
) | ||
}; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
#!/usr/bin/env bash | ||
PROGRAM_NAME="$1" | ||
ROOT_DIR="$(cd "$(dirname "$0")"; pwd)" | ||
#set -e | ||
PROGRAM_DIR=$ROOT_DIR/$PROGRAM_NAME | ||
cd $PROGRAM_DIR/pinocchio | ||
cargo build-sbf | ||
PROGRAM_NAME="pinocchio_rosetta_${PROGRAM_NAME//-/_}" SBF_OUT_DIR="$ROOT_DIR/target/deploy" cargo test --manifest-path "$PROGRAM_DIR/Cargo.toml" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
[package] | ||
name = "pinocchio-rosetta-transfer-lamports" | ||
version = "1.0.0" | ||
edition = "2021" | ||
|
||
[features] | ||
no-entrypoint = [] | ||
|
||
[dependencies] | ||
pinocchio = "0.6" | ||
|
||
[lib] | ||
crate-type = ["cdylib", "lib"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
//! Program entrypoint | ||
#![cfg(not(feature = "no-entrypoint"))] | ||
|
||
use pinocchio::{ | ||
lazy_entrypoint::{InstructionContext, MaybeAccount}, | ||
program_error::ProgramError, | ||
ProgramResult, | ||
}; | ||
|
||
// Since this is a single instruction program, we use the "lazy" variation | ||
// of the entrypoint. | ||
pinocchio::lazy_entrypoint!(process_instruction); | ||
|
||
#[inline] | ||
fn process_instruction(mut context: InstructionContext) -> ProgramResult { | ||
if context.remaining() != 2 { | ||
return Err(ProgramError::NotEnoughAccountKeys); | ||
} | ||
|
||
// This block is declared unsafe because: | ||
// | ||
// - We are using `next_account_unchecked`, which does not decrease the number of | ||
// remaining accounts in the context. This is ok because we know that we have | ||
// exactly two accounts. | ||
// | ||
// - We are using `assume_account` on the first account, which is ok because we | ||
// know that we have at least one account. | ||
// | ||
// - We are using `borrow_mut_lamports_unchecked`, which is ok because we know | ||
// that the lamports are not borrowed elsewhere and the accounts are different. | ||
unsafe { | ||
let source_info = context.next_account_unchecked().assume_account(); | ||
|
||
// The second account is the destination account – this one could be duplicated. | ||
// | ||
// We only need to transfer lamports from the source to the destination when the | ||
// accounts are different, so we can safely ignore the case when the account is | ||
// duplicated. | ||
if let MaybeAccount::Account(destination_info) = context.next_account_unchecked() { | ||
// withdraw five lamports | ||
*source_info.borrow_mut_lamports_unchecked() -= 5; | ||
// deposit five lamports | ||
*destination_info.borrow_mut_lamports_unchecked() += 5; | ||
} | ||
} | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
//! A program demonstrating the transfer of lamports | ||
#![deny(missing_docs)] | ||
|
||
mod entrypoint; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters