BPF rust language updates (#4752)

This commit is contained in:
Jack May 2019-06-20 16:07:12 -07:00 committed by GitHub
parent aacb38864c
commit e59b53dfa8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 230 additions and 180 deletions

View File

@ -10,14 +10,22 @@ source ci/rust-version.sh nightly
export RUST_BACKTRACE=1
export RUSTFLAGS="-D warnings"
(
for project in programs/bpf/rust/*/ ; do
(
cd "$project"
do_bpf_check() {
_ cargo +"$rust_stable" fmt --all -- --check
_ cargo +"$rust_nightly" clippy --all -- --version
_ cargo +"$rust_nightly" clippy --all -- --deny=warnings
_ cargo +"$rust_stable" audit
}
(
(
cd sdk/bpf/rust/rust-utils
do_bpf_check
)
for project in programs/bpf/rust/*/ ; do
(
cd "$project"
do_bpf_check
)
done
)

View File

@ -81,8 +81,9 @@ fn main() {
"cargo:warning=(not a warning) Building Rust-based BPF programs: solana_bpf_rust_{}",
program
);
assert!(Command::new("./build.sh")
assert!(Command::new("./do.sh")
.current_dir("rust")
.arg("build")
.arg(program)
.status()
.expect(&format!(

View File

@ -6,11 +6,10 @@
extern crate alloc;
extern crate solana_sdk_bpf_utils;
use solana_sdk_bpf_utils::log::*;
use alloc::vec::Vec;
use core::alloc::Layout;
use core::mem;
use solana_sdk_bpf_utils::info;
#[no_mangle]
pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
@ -20,7 +19,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
let layout = Layout::from_size_align(core::usize::MAX, mem::align_of::<u8>()).unwrap();
let ptr = alloc::alloc::alloc(layout);
if !ptr.is_null() {
sol_log("Error: Alloc of very larger buffer should fail");
info!("Error: Alloc of very larger buffer should fail");
panic!();
}
}
@ -31,7 +30,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
let layout = Layout::from_size_align(100, mem::align_of::<u8>()).unwrap();
let ptr = alloc::alloc::alloc(layout);
if ptr.is_null() {
sol_log("Error: Alloc of 100 bytes failed");
info!("Error: Alloc of 100 bytes failed");
alloc::alloc::handle_alloc_error(layout);
}
alloc::alloc::dealloc(ptr, layout);
@ -44,7 +43,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
let layout = Layout::from_size_align(100, mem::align_of::<u8>()).unwrap();
let ptr = alloc::alloc::alloc(layout);
if ptr.is_null() {
sol_log("Error: Alloc failed");
info!("Error: Alloc failed");
alloc::alloc::handle_alloc_error(layout);
}
for i in 0..ITERS {
@ -53,7 +52,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
for i in 0..ITERS {
assert_eq!(*ptr.add(i as usize), i as u8);
}
sol_log_64(0x3, 0, 0, 0, u64::from(*ptr.add(42)));
info!(0x3, 0, 0, 0, u64::from(*ptr.add(42)));
assert_eq!(*ptr.add(42), 42);
alloc::alloc::dealloc(ptr, layout);
}
@ -65,13 +64,13 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
// let layout = Layout::from_size_align(2048, mem::align_of::<u8>()).unwrap();
// let ptr = alloc::alloc::alloc(layout);
// if ptr.is_null() {
// sol_log("Error: Alloc of 2048 bytes failed");
// info!("Error: Alloc of 2048 bytes failed");
// alloc::alloc::handle_alloc_error(layout);
// }
// let layout = Layout::from_size_align(1, mem::align_of::<u8>()).unwrap();
// let ptr_fail = alloc::alloc::alloc(layout);
// if !ptr_fail.is_null() {
// sol_log("Error: Able to alloc 1 more then max");
// info!("Error: Able to alloc 1 more then max");
// panic!();
// }
// alloc::alloc::dealloc(ptr, layout);
@ -87,7 +86,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
for v in ones.iter() {
sum += ones[*v];
}
sol_log_64(0x0, 0, 0, 0, sum as u64);
info!(0x0, 0, 0, 0, sum as u64);
assert_eq!(sum, ITERS);
}
@ -98,13 +97,12 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
let mut v = Vec::new();
for i in 0..ITERS {
sol_log_64(i as u64, 0, 0, 0, 0);
v.push(i);
}
sol_log_64(0x4, 0, 0, 0, v.len() as u64);
info!(0x4, 0, 0, 0, v.len() as u64);
assert_eq!(v.len(), ITERS);
}
sol_log("Success");
info!("Success");
true
}

View File

@ -1,12 +0,0 @@
#!/usr/bin/env bash
if [ "$#" -ne 1 ]; then
# Build all projects
for project in */ ; do
./../../../sdk/bpf/rust/build.sh "$PWD/$project"
done
else
# Build requested project
./../../../sdk/bpf/rust/build.sh "$PWD/$1"
fi

View File

@ -1,12 +0,0 @@
#!/usr/bin/env bash
if [ "$#" -ne 1 ]; then
# Clean all projects
for project in */ ; do
./../../../sdk/bpf/rust/clean.sh "$PWD/$project"
done
else
# Clean requested project
./../../../sdk/bpf/rust/clean.sh "$PWD/$1"
fi

View File

@ -6,7 +6,7 @@
extern crate solana_sdk_bpf_utils;
use byteorder::{ByteOrder, LittleEndian};
use solana_sdk_bpf_utils::log::*;
use solana_sdk_bpf_utils::info;
#[no_mangle]
pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
@ -18,6 +18,6 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
LittleEndian::write_i16(&mut buf, -5_000);
assert_eq!(-5_000, LittleEndian::read_i16(&buf));
sol_log("Success");
info!("Success");
true
}

100
programs/bpf/rust/do.sh Executable file
View File

@ -0,0 +1,100 @@
#!/usr/bin/env bash
usage() {
echo ""
echo " Usage: do.sh action <project>"
echo ""
echo " If relative_project_path is ommitted then action will"
echo " be performed on all projects"
echo ""
echo " Supported actions:"
echo " build"
echo " clean"
echo " clippy"
echo " fmt"
echo ""
}
perform_action() {
set -e
case "$1" in
build)
./../../../sdk/bpf/rust/build.sh "$2"
;;
clean)
./../../../sdk/bpf/rust/clean.sh "$2"
;;
clippy)
(
cd "$2"
echo "clippy $2"
cargo +nightly clippy
)
;;
fmt)
(
cd "$2"
echo "formatting $2"
cargo fmt
)
;;
dump)
# Dump depends on tools that are not installed by default and must be installed manually
# - greadelf
# - llvm-objdump
# - rustfilt
(
pwd
./do.sh clean "$3"
./do.sh build "$3"
cd "$3"
set +e
cp ./target/dump.txt ./targetdump-last.txt 2>/dev/null
set -e
ls \
-la \
./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${3%/}".so \
> ./target/dump_mangled.txt
greadelf \
-aW \
./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${3%/}".so \
>> ./target/dump_mangled.txt
llvm-objdump \
-print-imm-hex \
--source \
--disassemble \
./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${3%/}".so \
>> ./target/dump_mangled.txt
sed \
s/://g \
< ./target/dump_mangled.txt \
| rustfilt \
> ./target/dump.txt
)
;;
help)
usage
exit
;;
*)
echo "Error: Unknown command"
usage
exit
;;
esac
}
set -e
if [ "$#" -ne 2 ]; then
# Build all projects
for project in */ ; do
perform_action "$1" "$PWD/$project" "$project"
done
else
# Build requested project
perform_action "$1" "$PWD/$2" "$2"
fi

View File

@ -1,21 +0,0 @@
#!/usr/bin/env bash
if [ "$#" -ne 1 ]; then
echo "Error: Must provide the name of the project to dump"
exit 1
fi
./clean.sh "$1"
./build.sh "$1"
cd "$1"
cp ./target/dump.txt ./targetdump-last.txt 2>/dev/null
set -ex
ls -la ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${1%/}".so > ./target/dump_mangled.txt
greadelf -aW ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${1%/}".so >> ./target/dump_mangled.txt
llvm-objdump -print-imm-hex --source --disassemble ./target/bpfel-unknown-unknown/release/solana_bpf_rust_"${1%/}".so >> ./target/dump_mangled.txt
sed s/://g < ./target/dump_mangled.txt | rustfilt > ./target/dump.txt

View File

@ -5,7 +5,7 @@
extern crate solana_sdk_bpf_utils;
use solana_sdk_bpf_utils::log::*;
use solana_sdk_bpf_utils::info;
#[no_mangle]
pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
@ -16,9 +16,9 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
for v in ones.iter() {
sum += *v;
}
sol_log_64(0xff, 0, 0, 0, sum);
info!(0xff, 0, 0, 0, sum);
assert_eq!(sum, ITERS as u64);
sol_log("Success");
info!("Success");
true
}

View File

@ -7,18 +7,18 @@ mod helper;
extern crate solana_sdk_bpf_utils;
use solana_sdk_bpf_utils::log::*;
use solana_sdk_bpf_utils::info;
#[no_mangle]
pub extern "C" fn entrypoint(_input: *mut u8) -> bool {
sol_log("call same package");
info!("call same package");
assert_eq!(crate::helper::many_args(1, 2, 3, 4, 5, 6, 7, 8, 9), 45);
sol_log("call another package");
info!("call another package");
assert_eq!(
solana_bpf_rust_many_args_dep::many_args(1, 2, 3, 4, 5, 6, 7, 8, 9),
45
);
sol_log("Success");
info!("Success");
true
}

View File

@ -0,0 +1,6 @@
[dependencies.compiler_builtins]
path = "../../../../sdk/bpf/dependencies/rust-bpf-sysroot/src/compiler-builtins"
features = ["c", "mem"]
[target.bpfel-unknown-unknown.dependencies]
alloc = { path = "../../../../sdk/bpf/dependencies/rust-bpf-sysroot/src/liballoc" }

View File

@ -4,7 +4,7 @@
extern crate solana_sdk_bpf_utils;
use solana_sdk_bpf_utils::log::*;
use solana_sdk_bpf_utils::info;
pub fn many_args(
arg1: u64,
@ -17,8 +17,8 @@ pub fn many_args(
arg8: u64,
arg9: u64,
) -> u64 {
sol_log("another package");
sol_log_64(arg1, arg2, arg3, arg4, arg5);
sol_log_64(arg6, arg7, arg8, arg9, 0);
info!("another package");
info!(arg1, arg2, arg3, arg4, arg5);
info!(arg6, arg7, arg8, arg9, 0);
arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9
}

View File

@ -2,12 +2,13 @@
#![no_std]
#![allow(unreachable_code)]
#![allow(unused_attributes)]
extern crate solana_sdk_bpf_utils;
use solana_sdk_bpf_utils::entrypoint;
use solana_sdk_bpf_utils::entrypoint::*;
use solana_sdk_bpf_utils::log::*;
use solana_sdk_bpf_utils::{entrypoint, info};
struct SStruct {
x: u64,
@ -21,18 +22,14 @@ fn return_sstruct() -> SStruct {
}
entrypoint!(process_instruction);
fn process_instruction(
ka: &mut [Option<SolKeyedAccount>; MAX_ACCOUNTS],
info: &SolClusterInfo,
data: &[u8],
) -> bool {
sol_log("Program identifier:");
fn process_instruction(ka: &mut [SolKeyedAccount], info: &SolClusterInfo, data: &[u8]) -> bool {
info!("Program identifier:");
sol_log_key(&info.program_id);
// Log the provided account keys and instruction input data. In the case of
// the no-op program, no account keys or input data are expected but real
// programs will have specific requirements so they can do their work.
sol_log("Account keys and instruction input data:");
info!("Account keys and instruction input data:");
sol_log_params(ka, data);
{
@ -49,7 +46,7 @@ fn process_instruction(
let result_str = core::str::from_utf8(&sparkle_heart).unwrap();
assert_eq!(4, result_str.len());
assert_eq!("💖", result_str);
sol_log(result_str);
info!(result_str);
}
{
@ -59,6 +56,6 @@ fn process_instruction(
assert_eq!(s.x + s.y + s.z, 6);
}
sol_log("Success");
info!("Success");
true
}

View File

@ -6,22 +6,14 @@
extern crate solana_sdk_bpf_utils;
use byteorder::{ByteOrder, LittleEndian};
use solana_sdk_bpf_utils::entrypoint;
use solana_sdk_bpf_utils::entrypoint::*;
use solana_sdk_bpf_utils::log::*;
use solana_sdk_bpf_utils::{entrypoint, info};
entrypoint!(process_instruction);
fn process_instruction(
ka: &mut [Option<SolKeyedAccount>; MAX_ACCOUNTS],
_info: &SolClusterInfo,
_data: &[u8],
) -> bool {
sol_log("Tick Height:");
if let Some(k) = &ka[2] {
let tick_height = LittleEndian::read_u64(k.data);
assert_eq!(10u64, tick_height);
sol_log("Success");
return true;
}
panic!();
fn process_instruction(ka: &mut [SolKeyedAccount], _info: &SolClusterInfo, _data: &[u8]) -> bool {
let tick_height = LittleEndian::read_u64(ka[2].data);
assert_eq!(10u64, tick_height);
info!("Success");
true
}

View File

@ -87,10 +87,10 @@ mod bpf {
let programs = [
("solana_bpf_rust_alloc", true),
("solana_bpf_rust_dep_crate", true),
("solana_bpf_rust_iter", true),
// ("solana_bpf_rust_many_args", true), // Issue #3099
("solana_bpf_rust_noop", true),
("solana_bpf_rust_dep_crate", true),
("solana_bpf_rust_panic", false),
("solana_bpf_rust_tick_height", true),
];

View File

@ -164,7 +164,7 @@ pub fn helper_sol_log(
let c_buf: *const c_char = addr as *const c_char;
let c_str: &CStr = unsafe { CStr::from_ptr(c_buf) };
match c_str.to_str() {
Ok(slice) => info!("sol_log: {:?}", slice),
Ok(slice) => info!("info!: {:?}", slice),
Err(e) => warn!("Error: Cannot print invalid string: {}", e),
};
0
@ -178,7 +178,7 @@ pub fn helper_sol_log_u64(
_context: &mut Option<Box<Any + 'static>>,
) -> u64 {
info!(
"sol_log_u64: {:#x}, {:#x}, {:#x}, {:#x}, {:#x}",
"info!: {:#x}, {:#x}, {:#x}, {:#x}, {:#x}",
arg1, arg2, arg3, arg4, arg5
);
0

View File

@ -9,6 +9,8 @@ if [ ! -f "$1/Cargo.toml" ]; then
exit 1
fi
echo "Building $1"
pushd "$(dirname "$0")"
bpf_sdk="$PWD/.."
popd
@ -28,7 +30,6 @@ export AR="$bpf_sdk/dependencies/llvm-native/bin/llvm-ar"
# Use the SDK's version of Rust to build for BPF
export RUSTUP_TOOLCHAIN=bpf
export RUSTFLAGS="
--emit=llvm-ir \
-C lto=no \
-C opt-level=2 \
-C link-arg=-z -C link-arg=notext \
@ -39,6 +40,6 @@ export RUSTFLAGS="
-C linker=$bpf_sdk/dependencies/llvm-native/bin/ld.lld"
export XARGO_HOME="$bpf_sdk/dependencies/xargo"
export XARGO_RUST_SRC="$bpf_sdk/dependencies/rust-bpf-sysroot/src"
xargo build --target bpfel-unknown-unknown --release -v
xargo build --target bpfel-unknown-unknown --release
{ { set +x; } 2>/dev/null; echo Success; }

View File

@ -1,24 +1,17 @@
//! @brief Solana Rust-based BPF program entrypoint and its parameter types
extern crate alloc;
use crate::log::*;
use alloc::vec::Vec;
use core::mem::size_of;
use core::slice::{from_raw_parts, from_raw_parts_mut};
/// Max number of accounts supported
pub const MAX_ACCOUNTS: usize = 10;
/// Size in bytes of a public key
pub const SIZE_PUBKEY: usize = 32;
/// Public key
pub struct SolPubkey<'a> {
pub key: &'a [u8; SIZE_PUBKEY],
}
pub type SolPubkey = [u8; 32];
/// Keyed Account
pub struct SolKeyedAccount<'a> {
/// Public key of the account
pub key: SolPubkey<'a>,
pub key: &'a SolPubkey,
/// Public key of the account
pub is_signer: bool,
/// Number of lamports owned by this account
@ -26,14 +19,14 @@ pub struct SolKeyedAccount<'a> {
/// On-chain data within this account
pub data: &'a mut [u8],
/// Program that owns this account
pub owner: SolPubkey<'a>,
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: SolPubkey<'a>,
/// program_id of the currently executing program
pub program_id: &'a SolPubkey,
}
/// Declare entrypoint of the program.
@ -48,9 +41,8 @@ macro_rules! entrypoint {
#[no_mangle]
pub unsafe extern "C" fn entrypoint(input: *mut u8) -> bool {
unsafe {
if let Ok((mut ka, info, data)) = $crate::entrypoint::deserialize(input) {
// Call use function
$process_instruction(&mut ka, &info, &data)
if let Ok((mut kas, info, data)) = $crate::entrypoint::deserialize(input) {
$process_instruction(&mut kas, &info, &data)
} else {
false
}
@ -63,32 +55,19 @@ macro_rules! entrypoint {
#[allow(clippy::type_complexity)]
pub unsafe fn deserialize<'a>(
input: *mut u8,
) -> Result<
(
[Option<SolKeyedAccount<'a>>; MAX_ACCOUNTS],
SolClusterInfo<'a>,
&'a [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 += 8;
offset += size_of::<u64>();
// KeyedAccounts
if num_ka > MAX_ACCOUNTS {
sol_log("Error: Too many accounts");
return Err(());
}
let mut kas: [Option<SolKeyedAccount>; MAX_ACCOUNTS] =
[None, None, None, None, None, None, None, None, None, None];
for ka in kas.iter_mut().take(num_ka) {
let mut kas = Vec::new();
for _ in 0..num_ka {
let is_signer = {
#[allow(clippy::cast_ptr_alignment)]
let is_signer_val = *(input.add(offset) as *const u64);
@ -96,12 +75,8 @@ pub unsafe fn deserialize<'a>(
};
offset += size_of::<u64>();
let key = {
SolPubkey {
key: &*(input.add(offset) as *mut [u8; SIZE_PUBKEY]),
}
};
offset += SIZE_PUBKEY;
let key: &SolPubkey = &*(input.add(offset) as *const [u8; size_of::<SolPubkey>()]);
offset += size_of::<SolPubkey>();
#[allow(clippy::cast_ptr_alignment)]
let lamports = *(input.add(offset) as *const u64);
@ -114,14 +89,10 @@ pub unsafe fn deserialize<'a>(
let data = { from_raw_parts_mut(input.add(offset), data_length) };
offset += data_length;
let owner = {
SolPubkey {
key: &*(input.add(offset) as *mut [u8; SIZE_PUBKEY]),
}
};
offset += SIZE_PUBKEY;
let owner: &SolPubkey = &*(input.add(offset) as *const [u8; size_of::<SolPubkey>()]);
offset += size_of::<SolPubkey>();
*ka = Some(SolKeyedAccount {
kas.push(SolKeyedAccount {
key,
is_signer,
lamports,
@ -139,14 +110,9 @@ pub unsafe fn deserialize<'a>(
let data = { from_raw_parts(input.add(offset), data_length) };
offset += data_length;
// Id
let program_id = {
SolPubkey {
key: &*(input.add(offset) as *mut [u8; SIZE_PUBKEY]),
}
};
// Program Id
let program_id: &SolPubkey = &*(input.add(offset) as *const [u8; size_of::<SolPubkey>()]);
let info = SolClusterInfo { program_id };
Ok((kas, info, data))

View File

@ -6,7 +6,8 @@
#![feature(panic_info_message)]
#![feature(compiler_builtins_lib)]
#![feature(lang_items)]
#[lang = "eh_personality"] extern fn eh_personality() {}
#[lang = "eh_personality"]
extern "C" fn eh_personality() {}
extern crate compiler_builtins;

View File

@ -2,13 +2,37 @@
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
#[inline(never)] // stack intensive, prevent inline so everyone does not incur cost
///
/// @param message - Message to print
#[inline(never)] // prevent inline so everyone does not incur stack cost
pub fn sol_log(message: &str) {
// TODO This is extremely slow, do something better
// Not pretty but 1/3 faster then using `clone_from_slice()`
let mut buf: [u8; 128] = [0; 128];
for (i, b) in message.as_bytes().iter().enumerate() {
if i >= 126 {
if i > 127 {
break;
}
buf[i] = *b;
@ -22,6 +46,8 @@ extern "C" {
}
/// 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);
@ -36,7 +62,7 @@ extern "C" {
/// @param - key The public key to print
#[allow(dead_code)]
pub fn sol_log_key(key: &SolPubkey) {
for (i, k) in key.key.iter().enumerate() {
for (i, k) in key.iter().enumerate() {
sol_log_64(0, 0, 0, i as u64, u64::from(*k));
}
}
@ -56,22 +82,20 @@ pub fn sol_log_slice(slice: &[u8]) {
/// @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: &[Option<SolKeyedAccount>], data: &[u8]) {
pub fn sol_log_params(ka: &[SolKeyedAccount], data: &[u8]) {
for (i, k) in ka.iter().enumerate() {
if let Some(k) = k {
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("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);

View File

@ -6,11 +6,12 @@ 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 >= 126 {
if i > 127 {
break;
}
file[i] = *c;