Split out Rust BPF no-std stuff (#4968)

This commit is contained in:
Jack May
2019-07-08 20:28:05 -08:00
committed by GitHub
parent 49250f62aa
commit f9a2254688
35 changed files with 164 additions and 217 deletions

View File

@ -1,23 +0,0 @@
//! @brief Solana Rust-based BPF program memory allocator shim
use crate::log::*;
use core::alloc::{GlobalAlloc, Layout};
pub struct Allocator;
unsafe impl GlobalAlloc for Allocator {
unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
sol_alloc_free_(layout.size() as u64, 0)
}
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
sol_alloc_free_(layout.size() as u64, ptr as u64);
}
}
extern "C" {
fn sol_alloc_free_(size: u64, ptr: u64) -> *mut u8;
}
#[alloc_error_handler]
fn my_alloc_error_handler(_: core::alloc::Layout) -> ! {
sol_log("alloc_error_handler");
panic!();
}

View File

@ -117,80 +117,3 @@ pub unsafe fn deserialize<'a>(
Ok((kas, info, data))
}
#[cfg(test)]
mod tests {
extern crate std;
use self::std::ffi::CStr;
use self::std::println;
use self::std::string::String;
use super::*;
use core::mem;
#[no_mangle]
fn sol_log_(message: *const u8) {
let scenario = get_log_scenario();
let c_str = unsafe { CStr::from_ptr(message as *const i8) };
let string = c_str.to_str().unwrap();
println!("{:?}", string);
}
#[no_mangle]
fn sol_log_64_(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) {
println!("{:?} {:?} {:?} {:?} {:?}", arg1, arg2, arg3, arg4, arg5);
}
#[test]
fn test_entrypoint() {
set_log_scenario(4);
set_log_64_scenario(4);
let mut input: [u8; 154] = [
1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 151, 116, 3, 85, 181, 39, 151, 99, 155,
29, 208, 191, 255, 191, 11, 161, 4, 43, 104, 189, 202, 240, 231, 111, 146, 255, 199,
71, 67, 34, 254, 68, 48, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 255, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9,
0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 190, 103, 191,
69, 193, 202, 38, 193, 95, 62, 131, 135, 105, 13, 142, 240, 155, 120, 177, 90, 212, 54,
10, 118, 40, 33, 192, 8, 54, 141, 187, 63,
];
if let Ok((mut ka, info, data)) = deserialize(&mut input[0] as *mut u8) {
let account0 = match mem::replace(&mut ka[0], None) {
Some(mut account0) => account0,
None => {
panic!("Error: account not found");
}
};
for k in ka[1..].iter() {
if let Some(_) = k {
panic!("Too many keyed accounts found");
}
}
assert_eq!(true, account0.is_signer);
let key: &[u8; SIZE_PUBKEY] = &[
151, 116, 3, 85, 181, 39, 151, 99, 155, 29, 208, 191, 255, 191, 11, 161, 4, 43,
104, 189, 202, 240, 231, 111, 146, 255, 199, 71, 67, 34, 254, 68,
];
assert_eq!(SIZE_PUBKEY, account0.key.key.len());
assert_eq!(key, account0.key.key);
assert_eq!(48, account0.lamports);
assert_eq!(1, account0.data.len());
let owner = &[0; SIZE_PUBKEY];
assert_eq!(SIZE_PUBKEY, account0.owner.key.len());
assert_eq!(owner, account0.owner.key);
let d = [1, 0, 0, 0, 0, 0, 0, 0, 1];
assert_eq!(9, data.len());
assert_eq!(d, data);
assert_eq!(1, info.tick_height);
let program_id: &[u8; SIZE_PUBKEY] = &[
190, 103, 191, 69, 193, 202, 38, 193, 95, 62, 131, 135, 105, 13, 142, 240, 155,
120, 177, 90, 212, 54, 10, 118, 40, 33, 192, 8, 54, 141, 187, 63,
];
assert_eq!(program_id, info.program_id.key);
} else {
panic!("Failed to deserialize");
}
}
}

View File

@ -1,20 +1,6 @@
//! @brief Solana Rust-based BPF program utility functions and types
#![no_std]
#![feature(allocator_api)]
#![feature(alloc_error_handler)]
#![feature(panic_info_message)]
#![feature(compiler_builtins_lib)]
#![feature(lang_items)]
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
extern crate compiler_builtins;
pub mod allocator;
pub mod entrypoint;
pub mod log;
pub mod panic;
#[global_allocator]
static A: allocator::Allocator = allocator::Allocator;

View File

@ -91,122 +91,3 @@ pub fn sol_log_params(ka: &[SolKeyedAccount], data: &[u8]) {
sol_log("Instruction data");
sol_log_slice(data);
}
#[cfg(test)]
mod tests {
extern crate std;
use self::std::ffi::CStr;
use self::std::println;
use self::std::string::String;
use super::*;
use core::mem;
static mut _LOG_SCENARIO: u64 = 4;
fn get_log_scenario() -> u64 {
unsafe { _LOG_SCENARIO }
}
fn set_log_scenario(test: u64) {
unsafe { _LOG_SCENARIO = test };
}
#[no_mangle]
fn sol_log_(message: *const u8) {
let scenario = get_log_scenario();
let c_str = unsafe { CStr::from_ptr(message as *const i8) };
let string = c_str.to_str().unwrap();
match scenario {
1 => assert_eq!(string, "This is a test message"),
2 => assert_eq!(string, "Attempted to log a string that is too long"),
3 => {
let s: String = ['a'; 126].iter().collect();
assert_eq!(string, s);
}
4 => println!("{:?}", string),
_ => panic!("Unknown sol_log test"),
}
}
static mut _LOG_64_SCENARIO: u64 = 4;
fn get_log_64_scenario() -> u64 {
unsafe { _LOG_64_SCENARIO }
}
fn set_log_64_scenario(test: u64) {
unsafe { _LOG_64_SCENARIO = test };
}
#[no_mangle]
fn sol_log_64_(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) {
let scenario = get_log_64_scenario();
match scenario {
1 => {
assert_eq!(1, arg1);
assert_eq!(2, arg2);
assert_eq!(3, arg3);
assert_eq!(4, arg4);
assert_eq!(5, arg5);
}
2 => {
assert_eq!(0, arg1);
assert_eq!(0, arg2);
assert_eq!(0, arg3);
assert_eq!(arg4 + 1, arg5);
}
3 => {
assert_eq!(0, arg1);
assert_eq!(0, arg2);
assert_eq!(0, arg3);
assert_eq!(arg4 + 1, arg5);
}
4 => println!("{:?} {:?} {:?} {:?} {:?}", arg1, arg2, arg3, arg4, arg5),
_ => panic!("Unknown sol_log_64 test"),
}
}
#[test]
fn test_sol_log() {
set_log_scenario(1);
sol_log("This is a test message");
}
#[test]
fn test_sol_log_long() {
set_log_scenario(3);
let s: String = ['a'; 256].iter().collect();
sol_log(&s);
}
#[test]
fn test_sol_log_max_length() {
set_log_scenario(3);
let s: String = ['a'; 126].iter().collect();
sol_log(&s);
}
#[test]
fn test_sol_log_64() {
set_log_64_scenario(1);
sol_log_64(1, 2, 3, 4, 5);
}
#[test]
fn test_sol_log_key() {
set_log_64_scenario(2);
let key_array = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
];
let key = SolPubkey { key: &key_array };
sol_log_key(&key);
}
#[test]
fn test_sol_log_slice() {
set_log_64_scenario(3);
let array = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
25, 26, 27, 28, 29, 30, 31, 32,
];
sol_log_slice(&array);
}
}

View File

@ -1,32 +0,0 @@
//! @brief Solana Rust-based BPF program panic handling
use core::panic::PanicInfo;
use core::ptr;
#[cfg(not(test))]
#[panic_handler]
fn panic(info: &PanicInfo) -> ! {
// Message is ignored for now to avoid incurring formatting program size overhead
match info.location() {
Some(location) => {
let mut file: [u8; 128] = [0; 128];
for (i, c) in location.file().as_bytes().iter().enumerate() {
if i > 127 {
break;
}
file[i] = *c;
}
unsafe {
sol_panic_(
file.as_ptr(),
u64::from(location.line()),
u64::from(location.column()),
);
}
}
None => unsafe { sol_panic_(ptr::null(), 0, 0) },
}
}
extern "C" {
pub fn sol_panic_(file: *const u8, line: u64, column: u64) -> !;
}