Rust BPF programs depend on Solana SDK (#5819)
This commit is contained in:
4
sdk/bpf/rust/rust-test/.gitignore
vendored
4
sdk/bpf/rust/rust-test/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
/target/
|
||||
|
||||
Cargo.lock
|
||||
/farf/
|
@ -1,13 +0,0 @@
|
||||
|
||||
[package]
|
||||
name = "solana-sdk-bpf-test"
|
||||
version = "0.19.0-pre0"
|
||||
description = "Solana BPF SDK Rust Cargo test utilities"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[workspace]
|
||||
members = []
|
@ -1,13 +0,0 @@
|
||||
//! @brief Solana Rust-based BPF program utility functions and types
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe fn sol_log_(message: *const u8, length: u64) {
|
||||
let slice = std::slice::from_raw_parts(message, length as usize);
|
||||
let string = std::str::from_utf8(&slice).unwrap();
|
||||
std::println!("{}", string);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub fn sol_log_64_(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) {
|
||||
std::println!("{} {} {} {} {}", arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
4
sdk/bpf/rust/rust-utils/.gitignore
vendored
4
sdk/bpf/rust/rust-utils/.gitignore
vendored
@ -1,4 +0,0 @@
|
||||
/target/
|
||||
|
||||
Cargo.lock
|
||||
/farf/
|
@ -1,13 +0,0 @@
|
||||
|
||||
[package]
|
||||
name = "solana-sdk-bpf-utils"
|
||||
version = "0.19.0-pre0"
|
||||
description = "Solana BPF SDK Rust Utils"
|
||||
authors = ["Solana Maintainers <maintainers@solana.com>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
edition = "2018"
|
||||
|
||||
[workspace]
|
||||
members = []
|
@ -1,119 +0,0 @@
|
||||
//! @brief Solana Rust-based BPF program entrypoint and its parameter types
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::mem::size_of;
|
||||
use core::slice::{from_raw_parts, from_raw_parts_mut};
|
||||
|
||||
/// Public key
|
||||
pub type SolPubkey = [u8; 32];
|
||||
|
||||
/// Keyed Account
|
||||
pub struct SolKeyedAccount<'a> {
|
||||
/// Public key of the account
|
||||
pub key: &'a SolPubkey,
|
||||
/// Public key of the account
|
||||
pub is_signer: bool,
|
||||
/// Number of lamports owned by this account
|
||||
pub lamports: &'a mut u64,
|
||||
/// On-chain data within this account
|
||||
pub data: &'a mut [u8],
|
||||
/// Program that owns this account
|
||||
pub owner: &'a SolPubkey,
|
||||
}
|
||||
|
||||
/// Information about the state of the cluster immediately before the program
|
||||
/// started executing the current instruction
|
||||
pub struct SolClusterInfo<'a> {
|
||||
/// program_id of the currently executing program
|
||||
pub program_id: &'a SolPubkey,
|
||||
}
|
||||
|
||||
/// Declare entrypoint of the program.
|
||||
///
|
||||
/// Deserialize the program input parameters and call
|
||||
/// a user defined entrypoint. Users must call
|
||||
/// this function otherwise an entrypoint for
|
||||
/// their program will not be created.
|
||||
#[macro_export]
|
||||
macro_rules! entrypoint {
|
||||
($process_instruction:ident) => {
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn entrypoint(input: *mut u8) -> bool {
|
||||
unsafe {
|
||||
if let Ok((mut kas, info, data)) = $crate::entrypoint::deserialize(input) {
|
||||
$process_instruction(&mut kas, &info, &data)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Deserialize the input parameters
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub unsafe fn deserialize<'a>(
|
||||
input: *mut u8,
|
||||
) -> Result<(Vec<SolKeyedAccount<'a>>, SolClusterInfo<'a>, &'a [u8]), ()> {
|
||||
let mut offset: usize = 0;
|
||||
|
||||
// Number of KeyedAccounts present
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
let num_ka = *(input.add(offset) as *const u64) as usize;
|
||||
offset += size_of::<u64>();
|
||||
|
||||
// KeyedAccounts
|
||||
|
||||
let mut kas = Vec::with_capacity(num_ka);
|
||||
for _ in 0..num_ka {
|
||||
let is_signer = {
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
let is_signer_val = *(input.add(offset) as *const u64);
|
||||
(is_signer_val != 0)
|
||||
};
|
||||
offset += size_of::<u64>();
|
||||
|
||||
let key: &SolPubkey = &*(input.add(offset) as *const [u8; size_of::<SolPubkey>()]);
|
||||
offset += size_of::<SolPubkey>();
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
let lamports = &mut *(input.add(offset) as *mut u64);
|
||||
offset += size_of::<u64>();
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
let data_length = *(input.add(offset) as *const u64) as usize;
|
||||
offset += size_of::<u64>();
|
||||
|
||||
let data = { from_raw_parts_mut(input.add(offset), data_length) };
|
||||
offset += data_length;
|
||||
|
||||
let owner: &SolPubkey = &*(input.add(offset) as *const [u8; size_of::<SolPubkey>()]);
|
||||
offset += size_of::<SolPubkey>();
|
||||
|
||||
kas.push(SolKeyedAccount {
|
||||
key,
|
||||
is_signer,
|
||||
lamports,
|
||||
data,
|
||||
owner,
|
||||
});
|
||||
}
|
||||
|
||||
// Instruction data
|
||||
|
||||
#[allow(clippy::cast_ptr_alignment)]
|
||||
let data_length = *(input.add(offset) as *const u64) as usize;
|
||||
offset += size_of::<u64>();
|
||||
|
||||
let data = { from_raw_parts(input.add(offset), data_length) };
|
||||
offset += data_length;
|
||||
|
||||
// Program Id
|
||||
|
||||
let program_id: &SolPubkey = &*(input.add(offset) as *const [u8; size_of::<SolPubkey>()]);
|
||||
let info = SolClusterInfo { program_id };
|
||||
|
||||
Ok((kas, info, data))
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
//! @brief Solana Rust-based BPF program utility functions and types
|
||||
|
||||
pub mod entrypoint;
|
||||
pub mod log;
|
@ -1,93 +0,0 @@
|
||||
//! @brief Solana Rust-based BPF program logging
|
||||
|
||||
use crate::entrypoint::{SolKeyedAccount, SolPubkey};
|
||||
|
||||
/// Prints a string
|
||||
/// There are two forms and are fast
|
||||
/// 1. Single string
|
||||
/// 2. 5 integers
|
||||
#[macro_export]
|
||||
macro_rules! info {
|
||||
($msg:expr) => {
|
||||
$crate::log::sol_log($msg)
|
||||
};
|
||||
($arg1:expr, $arg2:expr, $arg3:expr, $arg4:expr, $arg5:expr) => {
|
||||
$crate::log::sol_log_64(
|
||||
$arg1 as u64,
|
||||
$arg2 as u64,
|
||||
$arg3 as u64,
|
||||
$arg4 as u64,
|
||||
$arg5 as u64,
|
||||
)
|
||||
}; // `format!()` is not supported yet, Issue #3099
|
||||
// `format!()` incurs a very large runtime overhead so it should be used with care
|
||||
// ($($arg:tt)*) => ($crate::log::sol_log(&format!($($arg)*)));
|
||||
}
|
||||
|
||||
/// Prints a string to stdout
|
||||
///
|
||||
/// @param message - Message to print
|
||||
pub fn sol_log(message: &str) {
|
||||
unsafe {
|
||||
sol_log_(message.as_ptr(), message.len() as u64);
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
fn sol_log_(message: *const u8, length: u64);
|
||||
}
|
||||
|
||||
/// Prints 64 bit values represented as hexadecimal to stdout
|
||||
///
|
||||
/// @param argx - integer arguments to print
|
||||
pub fn sol_log_64(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) {
|
||||
unsafe {
|
||||
sol_log_64_(arg1, arg2, arg3, arg4, arg5);
|
||||
}
|
||||
}
|
||||
extern "C" {
|
||||
fn sol_log_64_(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64);
|
||||
}
|
||||
|
||||
/// Prints the hexadecimal representation of a public key
|
||||
///
|
||||
/// @param - key The public key to print
|
||||
#[allow(dead_code)]
|
||||
pub fn sol_log_key(key: &SolPubkey) {
|
||||
for (i, k) in key.iter().enumerate() {
|
||||
sol_log_64(0, 0, 0, i as u64, u64::from(*k));
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints the hexadecimal representation of a slice
|
||||
///
|
||||
/// @param slice - The array to print
|
||||
#[allow(dead_code)]
|
||||
pub fn sol_log_slice(slice: &[u8]) {
|
||||
for (i, s) in slice.iter().enumerate() {
|
||||
sol_log_64(0, 0, 0, i as u64, u64::from(*s));
|
||||
}
|
||||
}
|
||||
|
||||
/// Prints the hexadecimal representation of the program's input parameters
|
||||
///
|
||||
/// @param ka - A pointer to an array of `SolKeyedAccounts` to print
|
||||
/// @param data - A pointer to the instruction data to print
|
||||
#[allow(dead_code)]
|
||||
pub fn sol_log_params(ka: &[SolKeyedAccount], data: &[u8]) {
|
||||
for (i, k) in ka.iter().enumerate() {
|
||||
sol_log("SolKeyedAccount");
|
||||
sol_log_64(0, 0, 0, 0, i as u64);
|
||||
sol_log("- Is signer");
|
||||
sol_log_64(0, 0, 0, 0, k.is_signer as u64);
|
||||
sol_log("- Key");
|
||||
sol_log_key(&k.key);
|
||||
sol_log("- Lamports");
|
||||
sol_log_64(0, 0, 0, 0, *k.lamports);
|
||||
sol_log("- AccountData");
|
||||
sol_log_slice(k.data);
|
||||
sol_log("- Owner");
|
||||
sol_log_key(&k.owner);
|
||||
}
|
||||
sol_log("Instruction data");
|
||||
sol_log_slice(data);
|
||||
}
|
Reference in New Issue
Block a user