Add msg! macro for program logging, deprecate info! macro
This commit is contained in:
parent
254790f8c8
commit
6705b5a98c
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate alloc;
|
extern crate alloc;
|
||||||
use solana_program::{entrypoint::SUCCESS, info};
|
use solana_program::{entrypoint::SUCCESS, msg};
|
||||||
use std::{alloc::Layout, mem};
|
use std::{alloc::Layout, mem};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
|
@ -13,7 +13,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
let layout = Layout::from_size_align(std::usize::MAX, mem::align_of::<u8>()).unwrap();
|
let layout = Layout::from_size_align(std::usize::MAX, mem::align_of::<u8>()).unwrap();
|
||||||
let ptr = alloc::alloc::alloc(layout);
|
let ptr = alloc::alloc::alloc(layout);
|
||||||
if !ptr.is_null() {
|
if !ptr.is_null() {
|
||||||
info!("Error: Alloc of very larger buffer should fail");
|
msg!("Error: Alloc of very larger buffer should fail");
|
||||||
panic!();
|
panic!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
let layout = Layout::from_size_align(100, mem::align_of::<u8>()).unwrap();
|
let layout = Layout::from_size_align(100, mem::align_of::<u8>()).unwrap();
|
||||||
let ptr = alloc::alloc::alloc(layout);
|
let ptr = alloc::alloc::alloc(layout);
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
info!("Error: Alloc of 100 bytes failed");
|
msg!("Error: Alloc of 100 bytes failed");
|
||||||
alloc::alloc::handle_alloc_error(layout);
|
alloc::alloc::handle_alloc_error(layout);
|
||||||
}
|
}
|
||||||
alloc::alloc::dealloc(ptr, layout);
|
alloc::alloc::dealloc(ptr, layout);
|
||||||
|
@ -37,7 +37,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
let layout = Layout::from_size_align(ITERS, mem::align_of::<u8>()).unwrap();
|
let layout = Layout::from_size_align(ITERS, mem::align_of::<u8>()).unwrap();
|
||||||
let ptr = alloc::alloc::alloc(layout);
|
let ptr = alloc::alloc::alloc(layout);
|
||||||
if ptr.is_null() {
|
if ptr.is_null() {
|
||||||
info!("Error: Alloc failed");
|
msg!("Error: Alloc failed");
|
||||||
alloc::alloc::handle_alloc_error(layout);
|
alloc::alloc::handle_alloc_error(layout);
|
||||||
}
|
}
|
||||||
for i in 0..ITERS {
|
for i in 0..ITERS {
|
||||||
|
@ -46,7 +46,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
for i in 0..ITERS {
|
for i in 0..ITERS {
|
||||||
assert_eq!(*ptr.add(i as usize), i as u8);
|
assert_eq!(*ptr.add(i as usize), i as u8);
|
||||||
}
|
}
|
||||||
info!(0x3, 0, 0, 0, u64::from(*ptr.add(42)));
|
msg!(0x3, 0, 0, 0, u64::from(*ptr.add(42)));
|
||||||
assert_eq!(*ptr.add(42), 42);
|
assert_eq!(*ptr.add(42), 42);
|
||||||
alloc::alloc::dealloc(ptr, layout);
|
alloc::alloc::dealloc(ptr, layout);
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
for v in ones.iter() {
|
for v in ones.iter() {
|
||||||
sum += ones[*v];
|
sum += ones[*v];
|
||||||
}
|
}
|
||||||
info!(0x0, 0, 0, 0, sum as u64);
|
msg!(0x0, 0, 0, 0, sum as u64);
|
||||||
assert_eq!(sum, ITERS);
|
assert_eq!(sum, ITERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
for i in 0..ITERS {
|
for i in 0..ITERS {
|
||||||
v.push(i);
|
v.push(i);
|
||||||
}
|
}
|
||||||
info!(0x4, 0, 0, 0, v.len() as u64);
|
msg!(0x4, 0, 0, 0, v.len() as u64);
|
||||||
assert_eq!(v.len(), ITERS);
|
assert_eq!(v.len(), ITERS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
//! @brief Example Rust-based BPF program that tests call depth and stack usage
|
//! @brief Example Rust-based BPF program that tests call depth and stack usage
|
||||||
|
|
||||||
use solana_program::{entrypoint::SUCCESS, info};
|
use solana_program::{entrypoint::SUCCESS, msg};
|
||||||
|
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
pub fn recurse(data: &mut [u8]) {
|
pub fn recurse(data: &mut [u8]) {
|
||||||
|
@ -8,16 +8,16 @@ pub fn recurse(data: &mut [u8]) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
recurse(&mut data[1..]);
|
recurse(&mut data[1..]);
|
||||||
info!(line!(), 0, 0, 0, data[0]);
|
msg!(line!(), 0, 0, 0, data[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// # Safety
|
/// # Safety
|
||||||
#[inline(never)]
|
#[inline(never)]
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 {
|
pub unsafe extern "C" fn entrypoint(input: *mut u8) -> u64 {
|
||||||
info!("Call depth");
|
msg!("Call depth");
|
||||||
let depth = *(input.add(16) as *mut u8);
|
let depth = *(input.add(16) as *mut u8);
|
||||||
info!(line!(), 0, 0, 0, depth);
|
msg!(line!(), 0, 0, 0, depth);
|
||||||
let mut data = Vec::with_capacity(depth as usize);
|
let mut data = Vec::with_capacity(depth as usize);
|
||||||
for i in 0_u8..depth {
|
for i in 0_u8..depth {
|
||||||
data.push(i);
|
data.push(i);
|
||||||
|
|
|
@ -4,7 +4,7 @@ use solana_program::{
|
||||||
account_info::AccountInfo,
|
account_info::AccountInfo,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
entrypoint::{ProgramResult, HEAP_LENGTH, HEAP_START_ADDRESS},
|
entrypoint::{ProgramResult, HEAP_LENGTH, HEAP_START_ADDRESS},
|
||||||
info,
|
msg,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -58,7 +58,7 @@ fn process_instruction(
|
||||||
_accounts: &[AccountInfo],
|
_accounts: &[AccountInfo],
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("Custom heap");
|
msg!("Custom heap");
|
||||||
unsafe {
|
unsafe {
|
||||||
let layout = Layout::from_size_align(usize::MAX - 0x42, align_of::<u8>()).unwrap();
|
let layout = Layout::from_size_align(usize::MAX - 0x42, align_of::<u8>()).unwrap();
|
||||||
let ptr = alloc(layout);
|
let ptr = alloc(layout);
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, bpf_loader, entrypoint_deprecated,
|
account_info::AccountInfo, bpf_loader, entrypoint_deprecated,
|
||||||
entrypoint_deprecated::ProgramResult, info, log::*, pubkey::Pubkey,
|
entrypoint_deprecated::ProgramResult, log::*, msg, pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, PartialEq)]
|
#[derive(Debug, PartialEq)]
|
||||||
|
@ -26,7 +26,7 @@ fn process_instruction(
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("Program identifier:");
|
msg!("Program identifier:");
|
||||||
program_id.log();
|
program_id.log();
|
||||||
|
|
||||||
assert!(!bpf_loader::check_id(program_id));
|
assert!(!bpf_loader::check_id(program_id));
|
||||||
|
@ -34,7 +34,7 @@ fn process_instruction(
|
||||||
// Log the provided account keys and instruction input data. In the case of
|
// 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
|
// 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.
|
// programs will have specific requirements so they can do their work.
|
||||||
info!("Account keys and instruction input data:");
|
msg!("Account keys and instruction input data:");
|
||||||
sol_log_params(accounts, instruction_data);
|
sol_log_params(accounts, instruction_data);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@ fn process_instruction(
|
||||||
let result_str = std::str::from_utf8(&sparkle_heart).unwrap();
|
let result_str = std::str::from_utf8(&sparkle_heart).unwrap();
|
||||||
assert_eq!(4, result_str.len());
|
assert_eq!(4, result_str.len());
|
||||||
assert_eq!("💖", result_str);
|
assert_eq!("💖", result_str);
|
||||||
info!(result_str);
|
msg!(result_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, info,
|
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg,
|
||||||
program_error::ProgramError, pubkey::Pubkey,
|
program_error::ProgramError, pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -14,36 +14,36 @@ fn process_instruction(
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
match instruction_data[0] {
|
match instruction_data[0] {
|
||||||
1 => {
|
1 => {
|
||||||
info!("modify first account data");
|
msg!("modify first account data");
|
||||||
accounts[2].data.borrow_mut()[0] = 1;
|
accounts[2].data.borrow_mut()[0] = 1;
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
info!("modify first account data");
|
msg!("modify first account data");
|
||||||
accounts[3].data.borrow_mut()[0] = 2;
|
accounts[3].data.borrow_mut()[0] = 2;
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
info!("modify both account data");
|
msg!("modify both account data");
|
||||||
accounts[2].data.borrow_mut()[0] += 1;
|
accounts[2].data.borrow_mut()[0] += 1;
|
||||||
accounts[3].data.borrow_mut()[0] += 2;
|
accounts[3].data.borrow_mut()[0] += 2;
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
info!("modify first account lamports");
|
msg!("modify first account lamports");
|
||||||
**accounts[1].lamports.borrow_mut() -= 1;
|
**accounts[1].lamports.borrow_mut() -= 1;
|
||||||
**accounts[2].lamports.borrow_mut() += 1;
|
**accounts[2].lamports.borrow_mut() += 1;
|
||||||
}
|
}
|
||||||
5 => {
|
5 => {
|
||||||
info!("modify first account lamports");
|
msg!("modify first account lamports");
|
||||||
**accounts[1].lamports.borrow_mut() -= 2;
|
**accounts[1].lamports.borrow_mut() -= 2;
|
||||||
**accounts[3].lamports.borrow_mut() += 2;
|
**accounts[3].lamports.borrow_mut() += 2;
|
||||||
}
|
}
|
||||||
6 => {
|
6 => {
|
||||||
info!("modify both account lamports");
|
msg!("modify both account lamports");
|
||||||
**accounts[1].lamports.borrow_mut() -= 3;
|
**accounts[1].lamports.borrow_mut() -= 3;
|
||||||
**accounts[2].lamports.borrow_mut() += 1;
|
**accounts[2].lamports.borrow_mut() += 1;
|
||||||
**accounts[3].lamports.borrow_mut() += 2;
|
**accounts[3].lamports.borrow_mut() += 2;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
info!("Unrecognized command");
|
msg!("Unrecognized command");
|
||||||
return Err(ProgramError::InvalidArgument);
|
return Err(ProgramError::InvalidArgument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,7 @@ use solana_program::{
|
||||||
decode_error::DecodeError,
|
decode_error::DecodeError,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
entrypoint::ProgramResult,
|
entrypoint::ProgramResult,
|
||||||
info,
|
msg,
|
||||||
program_error::{PrintProgramError, ProgramError},
|
program_error::{PrintProgramError, ProgramError},
|
||||||
pubkey::{Pubkey, PubkeyError},
|
pubkey::{Pubkey, PubkeyError},
|
||||||
};
|
};
|
||||||
|
@ -38,8 +38,8 @@ impl PrintProgramError for MyError {
|
||||||
E: 'static + std::error::Error + DecodeError<E> + PrintProgramError + FromPrimitive,
|
E: 'static + std::error::Error + DecodeError<E> + PrintProgramError + FromPrimitive,
|
||||||
{
|
{
|
||||||
match self {
|
match self {
|
||||||
MyError::DefaultEnumStart => info!("Error: Default enum start"),
|
MyError::DefaultEnumStart => msg!("Error: Default enum start"),
|
||||||
MyError::TheAnswer => info!("Error: The Answer"),
|
MyError::TheAnswer => msg!("Error: The Answer"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,19 +52,19 @@ fn process_instruction(
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
match instruction_data[0] {
|
match instruction_data[0] {
|
||||||
1 => {
|
1 => {
|
||||||
info!("return success");
|
msg!("return success");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
2 => {
|
2 => {
|
||||||
info!("return a builtin");
|
msg!("return a builtin");
|
||||||
Err(ProgramError::InvalidAccountData)
|
Err(ProgramError::InvalidAccountData)
|
||||||
}
|
}
|
||||||
3 => {
|
3 => {
|
||||||
info!("return default enum start value");
|
msg!("return default enum start value");
|
||||||
Err(MyError::DefaultEnumStart.into())
|
Err(MyError::DefaultEnumStart.into())
|
||||||
}
|
}
|
||||||
4 => {
|
4 => {
|
||||||
info!("return custom error");
|
msg!("return custom error");
|
||||||
Err(MyError::TheAnswer.into())
|
Err(MyError::TheAnswer.into())
|
||||||
}
|
}
|
||||||
7 => {
|
7 => {
|
||||||
|
@ -74,11 +74,11 @@ fn process_instruction(
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
9 => {
|
9 => {
|
||||||
info!("return pubkey error");
|
msg!("return pubkey error");
|
||||||
Err(PubkeyError::MaxSeedLengthExceeded.into())
|
Err(PubkeyError::MaxSeedLengthExceeded.into())
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
info!("Unsupported");
|
msg!("Unsupported");
|
||||||
Err(ProgramError::InvalidInstructionData)
|
Err(ProgramError::InvalidInstructionData)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::next_account_info, account_info::AccountInfo, entrypoint,
|
account_info::next_account_info, account_info::AccountInfo, entrypoint,
|
||||||
entrypoint::ProgramResult, info, program_error::ProgramError, pubkey::Pubkey,
|
entrypoint::ProgramResult, msg, program_error::ProgramError, pubkey::Pubkey,
|
||||||
sysvar::instructions,
|
sysvar::instructions,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -37,9 +37,9 @@ fn process_instruction(
|
||||||
let my_index = instruction_data[1] as u16;
|
let my_index = instruction_data[1] as u16;
|
||||||
assert_eq!(current_instruction, my_index);
|
assert_eq!(current_instruction, my_index);
|
||||||
|
|
||||||
info!(&format!("id: {}", instruction.program_id));
|
msg!(&format!("id: {}", instruction.program_id));
|
||||||
|
|
||||||
info!(&format!("data[0]: {}", instruction.data[0]));
|
msg!(&format!("data[0]: {}", instruction.data[0]));
|
||||||
info!(&format!("index: {}", current_instruction));
|
msg!(&format!("index: {}", current_instruction));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ use solana_program::{
|
||||||
account_info::AccountInfo,
|
account_info::AccountInfo,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
entrypoint::{ProgramResult, MAX_PERMITTED_DATA_INCREASE},
|
entrypoint::{ProgramResult, MAX_PERMITTED_DATA_INCREASE},
|
||||||
info,
|
msg,
|
||||||
program::{invoke, invoke_signed},
|
program::{invoke, invoke_signed},
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::{Pubkey, PubkeyError},
|
pubkey::{Pubkey, PubkeyError},
|
||||||
|
@ -39,7 +39,7 @@ fn process_instruction(
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("invoke Rust program");
|
msg!("invoke Rust program");
|
||||||
|
|
||||||
let bump_seed1 = instruction_data[1];
|
let bump_seed1 = instruction_data[1];
|
||||||
let bump_seed2 = instruction_data[2];
|
let bump_seed2 = instruction_data[2];
|
||||||
|
@ -47,7 +47,7 @@ fn process_instruction(
|
||||||
|
|
||||||
match instruction_data[0] {
|
match instruction_data[0] {
|
||||||
TEST_SUCCESS => {
|
TEST_SUCCESS => {
|
||||||
info!("Call system program create account");
|
msg!("Call system program create account");
|
||||||
{
|
{
|
||||||
let from_lamports = accounts[FROM_INDEX].lamports();
|
let from_lamports = accounts[FROM_INDEX].lamports();
|
||||||
let to_lamports = accounts[DERIVED_KEY1_INDEX].lamports();
|
let to_lamports = accounts[DERIVED_KEY1_INDEX].lamports();
|
||||||
|
@ -85,7 +85,7 @@ fn process_instruction(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Call system program transfer");
|
msg!("Call system program transfer");
|
||||||
{
|
{
|
||||||
let from_lamports = accounts[FROM_INDEX].lamports();
|
let from_lamports = accounts[FROM_INDEX].lamports();
|
||||||
let to_lamports = accounts[DERIVED_KEY1_INDEX].lamports();
|
let to_lamports = accounts[DERIVED_KEY1_INDEX].lamports();
|
||||||
|
@ -99,7 +99,7 @@ fn process_instruction(
|
||||||
assert_eq!(accounts[DERIVED_KEY1_INDEX].lamports(), to_lamports + 1);
|
assert_eq!(accounts[DERIVED_KEY1_INDEX].lamports(), to_lamports + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Test data translation");
|
msg!("Test data translation");
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
let mut data = accounts[ARGUMENT_INDEX].try_borrow_mut_data()?;
|
let mut data = accounts[ARGUMENT_INDEX].try_borrow_mut_data()?;
|
||||||
|
@ -121,7 +121,7 @@ fn process_instruction(
|
||||||
invoke(&instruction, accounts)?;
|
invoke(&instruction, accounts)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Test no instruction data");
|
msg!("Test no instruction data");
|
||||||
{
|
{
|
||||||
let instruction = create_instruction(
|
let instruction = create_instruction(
|
||||||
*accounts[INVOKED_PROGRAM_INDEX].key,
|
*accounts[INVOKED_PROGRAM_INDEX].key,
|
||||||
|
@ -131,7 +131,7 @@ fn process_instruction(
|
||||||
invoke(&instruction, accounts)?;
|
invoke(&instruction, accounts)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Test return error");
|
msg!("Test return error");
|
||||||
{
|
{
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
10,
|
10,
|
||||||
|
@ -154,7 +154,7 @@ fn process_instruction(
|
||||||
assert_eq!(0, accounts[INVOKED_ARGUMENT_INDEX].try_borrow_data()?[0]);
|
assert_eq!(0, accounts[INVOKED_ARGUMENT_INDEX].try_borrow_data()?[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Test refcell usage");
|
msg!("Test refcell usage");
|
||||||
{
|
{
|
||||||
let writable = INVOKED_ARGUMENT_INDEX;
|
let writable = INVOKED_ARGUMENT_INDEX;
|
||||||
let readable = INVOKED_PROGRAM_INDEX;
|
let readable = INVOKED_PROGRAM_INDEX;
|
||||||
|
@ -240,7 +240,7 @@ fn process_instruction(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Test create_program_address");
|
msg!("Test create_program_address");
|
||||||
{
|
{
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
&Pubkey::create_program_address(
|
&Pubkey::create_program_address(
|
||||||
|
@ -256,7 +256,7 @@ fn process_instruction(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Test derived signers");
|
msg!("Test derived signers");
|
||||||
{
|
{
|
||||||
assert!(!accounts[DERIVED_KEY1_INDEX].is_signer);
|
assert!(!accounts[DERIVED_KEY1_INDEX].is_signer);
|
||||||
assert!(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
assert!(!accounts[DERIVED_KEY2_INDEX].is_signer);
|
||||||
|
@ -279,7 +279,7 @@ fn process_instruction(
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Test readonly with writable account");
|
msg!("Test readonly with writable account");
|
||||||
{
|
{
|
||||||
let invoked_instruction = create_instruction(
|
let invoked_instruction = create_instruction(
|
||||||
*accounts[INVOKED_PROGRAM_INDEX].key,
|
*accounts[INVOKED_PROGRAM_INDEX].key,
|
||||||
|
@ -289,14 +289,14 @@ fn process_instruction(
|
||||||
invoke(&invoked_instruction, accounts)?;
|
invoke(&invoked_instruction, accounts)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Test nested invoke");
|
msg!("Test nested invoke");
|
||||||
{
|
{
|
||||||
assert!(accounts[ARGUMENT_INDEX].is_signer);
|
assert!(accounts[ARGUMENT_INDEX].is_signer);
|
||||||
|
|
||||||
**accounts[ARGUMENT_INDEX].lamports.borrow_mut() -= 5;
|
**accounts[ARGUMENT_INDEX].lamports.borrow_mut() -= 5;
|
||||||
**accounts[INVOKED_ARGUMENT_INDEX].lamports.borrow_mut() += 5;
|
**accounts[INVOKED_ARGUMENT_INDEX].lamports.borrow_mut() += 5;
|
||||||
|
|
||||||
info!("First invoke");
|
msg!("First invoke");
|
||||||
let instruction = create_instruction(
|
let instruction = create_instruction(
|
||||||
*accounts[INVOKED_PROGRAM_INDEX].key,
|
*accounts[INVOKED_PROGRAM_INDEX].key,
|
||||||
&[
|
&[
|
||||||
|
@ -308,7 +308,7 @@ fn process_instruction(
|
||||||
vec![TEST_NESTED_INVOKE],
|
vec![TEST_NESTED_INVOKE],
|
||||||
);
|
);
|
||||||
invoke(&instruction, accounts)?;
|
invoke(&instruction, accounts)?;
|
||||||
info!("2nd invoke from first program");
|
msg!("2nd invoke from first program");
|
||||||
invoke(&instruction, accounts)?;
|
invoke(&instruction, accounts)?;
|
||||||
|
|
||||||
assert_eq!(accounts[ARGUMENT_INDEX].lamports(), 42 - 5 + 1 + 1 + 1 + 1);
|
assert_eq!(accounts[ARGUMENT_INDEX].lamports(), 42 - 5 + 1 + 1 + 1 + 1);
|
||||||
|
@ -318,7 +318,7 @@ fn process_instruction(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
info!("Verify data values are retained and updated");
|
msg!("Verify data values are retained and updated");
|
||||||
{
|
{
|
||||||
let data = accounts[ARGUMENT_INDEX].try_borrow_data()?;
|
let data = accounts[ARGUMENT_INDEX].try_borrow_data()?;
|
||||||
for i in 0..100 {
|
for i in 0..100 {
|
||||||
|
@ -331,7 +331,7 @@ fn process_instruction(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TEST_PRIVILEGE_ESCALATION_SIGNER => {
|
TEST_PRIVILEGE_ESCALATION_SIGNER => {
|
||||||
info!("Test privilege escalation signer");
|
msg!("Test privilege escalation signer");
|
||||||
let mut invoked_instruction = create_instruction(
|
let mut invoked_instruction = create_instruction(
|
||||||
*accounts[INVOKED_PROGRAM_INDEX].key,
|
*accounts[INVOKED_PROGRAM_INDEX].key,
|
||||||
&[(accounts[DERIVED_KEY3_INDEX].key, false, false)],
|
&[(accounts[DERIVED_KEY3_INDEX].key, false, false)],
|
||||||
|
@ -344,7 +344,7 @@ fn process_instruction(
|
||||||
invoke(&invoked_instruction, accounts)?;
|
invoke(&invoked_instruction, accounts)?;
|
||||||
}
|
}
|
||||||
TEST_PRIVILEGE_ESCALATION_WRITABLE => {
|
TEST_PRIVILEGE_ESCALATION_WRITABLE => {
|
||||||
info!("Test privilege escalation writable");
|
msg!("Test privilege escalation writable");
|
||||||
let mut invoked_instruction = create_instruction(
|
let mut invoked_instruction = create_instruction(
|
||||||
*accounts[INVOKED_PROGRAM_INDEX].key,
|
*accounts[INVOKED_PROGRAM_INDEX].key,
|
||||||
&[(accounts[DERIVED_KEY3_INDEX].key, false, false)],
|
&[(accounts[DERIVED_KEY3_INDEX].key, false, false)],
|
||||||
|
@ -358,7 +358,7 @@ fn process_instruction(
|
||||||
invoke(&invoked_instruction, accounts)?;
|
invoke(&invoked_instruction, accounts)?;
|
||||||
}
|
}
|
||||||
TEST_PPROGRAM_NOT_EXECUTABLE => {
|
TEST_PPROGRAM_NOT_EXECUTABLE => {
|
||||||
info!("Test program not executable");
|
msg!("Test program not executable");
|
||||||
let instruction = create_instruction(
|
let instruction = create_instruction(
|
||||||
*accounts[ARGUMENT_INDEX].key,
|
*accounts[ARGUMENT_INDEX].key,
|
||||||
&[(accounts[ARGUMENT_INDEX].key, true, true)],
|
&[(accounts[ARGUMENT_INDEX].key, true, true)],
|
||||||
|
|
|
@ -7,7 +7,7 @@ use solana_program::{
|
||||||
account_info::AccountInfo,
|
account_info::AccountInfo,
|
||||||
bpf_loader, entrypoint,
|
bpf_loader, entrypoint,
|
||||||
entrypoint::ProgramResult,
|
entrypoint::ProgramResult,
|
||||||
info,
|
msg,
|
||||||
program::{invoke, invoke_signed},
|
program::{invoke, invoke_signed},
|
||||||
program_error::ProgramError,
|
program_error::ProgramError,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
|
@ -20,7 +20,7 @@ fn process_instruction(
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("Invoked program");
|
msg!("Invoked program");
|
||||||
|
|
||||||
if instruction_data.is_empty() {
|
if instruction_data.is_empty() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
|
@ -28,7 +28,7 @@ fn process_instruction(
|
||||||
|
|
||||||
match instruction_data[0] {
|
match instruction_data[0] {
|
||||||
TEST_VERIFY_TRANSLATIONS => {
|
TEST_VERIFY_TRANSLATIONS => {
|
||||||
info!("verify data translations");
|
msg!("verify data translations");
|
||||||
|
|
||||||
const ARGUMENT_INDEX: usize = 0;
|
const ARGUMENT_INDEX: usize = 0;
|
||||||
const INVOKED_ARGUMENT_INDEX: usize = 1;
|
const INVOKED_ARGUMENT_INDEX: usize = 1;
|
||||||
|
@ -102,11 +102,11 @@ fn process_instruction(
|
||||||
assert!(accounts[INVOKED_PROGRAM_DUP_INDEX]
|
assert!(accounts[INVOKED_PROGRAM_DUP_INDEX]
|
||||||
.try_borrow_mut_data()
|
.try_borrow_mut_data()
|
||||||
.is_err());
|
.is_err());
|
||||||
info!(data[0], 0, 0, 0, 0);
|
msg!(data[0], 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TEST_RETURN_ERROR => {
|
TEST_RETURN_ERROR => {
|
||||||
info!("return error");
|
msg!("return error");
|
||||||
const ARGUMENT_INDEX: usize = 0;
|
const ARGUMENT_INDEX: usize = 0;
|
||||||
|
|
||||||
// modify lamports that should be dropped
|
// modify lamports that should be dropped
|
||||||
|
@ -118,7 +118,7 @@ fn process_instruction(
|
||||||
return Err(ProgramError::Custom(42));
|
return Err(ProgramError::Custom(42));
|
||||||
}
|
}
|
||||||
TEST_DERIVED_SIGNERS => {
|
TEST_DERIVED_SIGNERS => {
|
||||||
info!("verify derived signers");
|
msg!("verify derived signers");
|
||||||
const INVOKED_PROGRAM_INDEX: usize = 0;
|
const INVOKED_PROGRAM_INDEX: usize = 0;
|
||||||
const DERIVED_KEY1_INDEX: usize = 1;
|
const DERIVED_KEY1_INDEX: usize = 1;
|
||||||
const DERIVED_KEY2_INDEX: usize = 2;
|
const DERIVED_KEY2_INDEX: usize = 2;
|
||||||
|
@ -149,7 +149,7 @@ fn process_instruction(
|
||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
TEST_VERIFY_NESTED_SIGNERS => {
|
TEST_VERIFY_NESTED_SIGNERS => {
|
||||||
info!("verify nested derived signers");
|
msg!("verify nested derived signers");
|
||||||
const DERIVED_KEY1_INDEX: usize = 0;
|
const DERIVED_KEY1_INDEX: usize = 0;
|
||||||
const DERIVED_KEY2_INDEX: usize = 1;
|
const DERIVED_KEY2_INDEX: usize = 1;
|
||||||
const DERIVED_KEY3_INDEX: usize = 2;
|
const DERIVED_KEY3_INDEX: usize = 2;
|
||||||
|
@ -159,16 +159,16 @@ fn process_instruction(
|
||||||
assert!(accounts[DERIVED_KEY3_INDEX].is_signer);
|
assert!(accounts[DERIVED_KEY3_INDEX].is_signer);
|
||||||
}
|
}
|
||||||
TEST_VERIFY_WRITER => {
|
TEST_VERIFY_WRITER => {
|
||||||
info!("verify writable");
|
msg!("verify writable");
|
||||||
const ARGUMENT_INDEX: usize = 0;
|
const ARGUMENT_INDEX: usize = 0;
|
||||||
|
|
||||||
assert!(!accounts[ARGUMENT_INDEX].is_writable);
|
assert!(!accounts[ARGUMENT_INDEX].is_writable);
|
||||||
}
|
}
|
||||||
TEST_VERIFY_PRIVILEGE_ESCALATION => {
|
TEST_VERIFY_PRIVILEGE_ESCALATION => {
|
||||||
info!("Success");
|
msg!("Success");
|
||||||
}
|
}
|
||||||
TEST_NESTED_INVOKE => {
|
TEST_NESTED_INVOKE => {
|
||||||
info!("nested invoke");
|
msg!("nested invoke");
|
||||||
|
|
||||||
const ARGUMENT_INDEX: usize = 0;
|
const ARGUMENT_INDEX: usize = 0;
|
||||||
const INVOKED_ARGUMENT_INDEX: usize = 1;
|
const INVOKED_ARGUMENT_INDEX: usize = 1;
|
||||||
|
@ -179,7 +179,7 @@ fn process_instruction(
|
||||||
**accounts[INVOKED_ARGUMENT_INDEX].lamports.borrow_mut() -= 1;
|
**accounts[INVOKED_ARGUMENT_INDEX].lamports.borrow_mut() -= 1;
|
||||||
**accounts[ARGUMENT_INDEX].lamports.borrow_mut() += 1;
|
**accounts[ARGUMENT_INDEX].lamports.borrow_mut() += 1;
|
||||||
if accounts.len() > 2 {
|
if accounts.len() > 2 {
|
||||||
info!("Invoke again");
|
msg!("Invoke again");
|
||||||
let invoked_instruction = create_instruction(
|
let invoked_instruction = create_instruction(
|
||||||
*accounts[INVOKED_PROGRAM_INDEX].key,
|
*accounts[INVOKED_PROGRAM_INDEX].key,
|
||||||
&[
|
&[
|
||||||
|
@ -190,7 +190,7 @@ fn process_instruction(
|
||||||
);
|
);
|
||||||
invoke(&invoked_instruction, accounts)?;
|
invoke(&invoked_instruction, accounts)?;
|
||||||
} else {
|
} else {
|
||||||
info!("Last invoked");
|
msg!("Last invoked");
|
||||||
{
|
{
|
||||||
let mut data = accounts[INVOKED_ARGUMENT_INDEX].try_borrow_mut_data()?;
|
let mut data = accounts[INVOKED_ARGUMENT_INDEX].try_borrow_mut_data()?;
|
||||||
for i in 0..10 {
|
for i in 0..10 {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! @brief Example Rust-based BPF program tests loop iteration
|
//! @brief Example Rust-based BPF program tests loop iteration
|
||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{entrypoint::SUCCESS, info};
|
use solana_program::{entrypoint::SUCCESS, msg};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
|
@ -12,7 +12,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
for v in ones.iter() {
|
for v in ones.iter() {
|
||||||
sum += *v;
|
sum += *v;
|
||||||
}
|
}
|
||||||
info!(0xff, 0, 0, 0, sum);
|
msg!(0xff, 0, 0, 0, sum);
|
||||||
assert_eq!(sum, ITERS as u64);
|
assert_eq!(sum, ITERS as u64);
|
||||||
|
|
||||||
SUCCESS
|
SUCCESS
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
|
|
||||||
mod helper;
|
mod helper;
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{entrypoint::SUCCESS, info};
|
use solana_program::{entrypoint::SUCCESS, msg};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
info!("Call same package");
|
msg!("Call same package");
|
||||||
assert_eq!(crate::helper::many_args(1, 2, 3, 4, 5, 6, 7, 8, 9), 45);
|
assert_eq!(crate::helper::many_args(1, 2, 3, 4, 5, 6, 7, 8, 9), 45);
|
||||||
|
|
||||||
info!("Call another package");
|
msg!("Call another package");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
solana_bpf_rust_many_args_dep::many_args(1, 2, 3, 4, 5, 6, 7, 8, 9),
|
solana_bpf_rust_many_args_dep::many_args(1, 2, 3, 4, 5, 6, 7, 8, 9),
|
||||||
45
|
45
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
//! @brief Solana Rust-based BPF program utility functions and types
|
//! @brief Solana Rust-based BPF program utility functions and types
|
||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::info;
|
use solana_program::msg;
|
||||||
|
|
||||||
pub fn many_args(
|
pub fn many_args(
|
||||||
arg1: u64,
|
arg1: u64,
|
||||||
|
@ -14,9 +14,9 @@ pub fn many_args(
|
||||||
arg8: u64,
|
arg8: u64,
|
||||||
arg9: u64,
|
arg9: u64,
|
||||||
) -> u64 {
|
) -> u64 {
|
||||||
info!("Another package - many_args");
|
msg!("Another package - many_args");
|
||||||
info!(arg1, arg2, arg3, arg4, arg5);
|
msg!(arg1, arg2, arg3, arg4, arg5);
|
||||||
info!(arg6, arg7, arg8, arg9, 0);
|
msg!(arg6, arg7, arg8, arg9, 0);
|
||||||
arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9
|
arg1 + arg2 + arg3 + arg4 + arg5 + arg6 + arg7 + arg8 + arg9
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,9 +38,9 @@ pub fn many_args_sret(
|
||||||
arg8: u64,
|
arg8: u64,
|
||||||
arg9: u64,
|
arg9: u64,
|
||||||
) -> Ret {
|
) -> Ret {
|
||||||
info!("Another package - many_args_sret");
|
msg!("Another package - many_args_sret");
|
||||||
info!(arg1, arg2, arg3, arg4, arg5);
|
msg!(arg1, arg2, arg3, arg4, arg5);
|
||||||
info!(arg6, arg7, arg8, arg9, 0);
|
msg!(arg6, arg7, arg8, arg9, 0);
|
||||||
Ret {
|
Ret {
|
||||||
group1: u128::from(arg1) + u128::from(arg2) + u128::from(arg3),
|
group1: u128::from(arg1) + u128::from(arg2) + u128::from(arg3),
|
||||||
group2: u128::from(arg4) + u128::from(arg5) + u128::from(arg6),
|
group2: u128::from(arg4) + u128::from(arg5) + u128::from(arg6),
|
||||||
|
|
|
@ -4,8 +4,8 @@
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
fn custom_panic(info: &core::panic::PanicInfo<'_>) {
|
fn custom_panic(info: &core::panic::PanicInfo<'_>) {
|
||||||
// Note: Full panic reporting is included here for testing purposes
|
// Note: Full panic reporting is included here for testing purposes
|
||||||
solana_program::info!("program custom panic enabled");
|
solana_program::msg!("program custom panic enabled");
|
||||||
solana_program::info!(&format!("{}", info));
|
solana_program::msg!(&format!("{}", info));
|
||||||
}
|
}
|
||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_bpf_rust_param_passing_dep::{Data, TestDep};
|
use solana_bpf_rust_param_passing_dep::{Data, TestDep};
|
||||||
use solana_program::{entrypoint::SUCCESS, info};
|
use solana_program::{entrypoint::SUCCESS, msg};
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
|
@ -17,7 +17,7 @@ pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
};
|
};
|
||||||
|
|
||||||
let test_dep = TestDep::new(&data, 1, 2, 3, 4, 5);
|
let test_dep = TestDep::new(&data, 1, 2, 3, 4, 5);
|
||||||
info!(0, 0, 0, 0, test_dep.thirty);
|
msg!(0, 0, 0, 0, test_dep.thirty);
|
||||||
assert!(test_dep.thirty == 30);
|
assert!(test_dep.thirty == 30);
|
||||||
|
|
||||||
SUCCESS
|
SUCCESS
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, info, pubkey::Pubkey,
|
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
|
||||||
entrypoint!(process_instruction);
|
entrypoint!(process_instruction);
|
||||||
|
@ -13,6 +13,6 @@ fn process_instruction(
|
||||||
_accounts: &[AccountInfo],
|
_accounts: &[AccountInfo],
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("rand");
|
msg!("rand");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ pub mod ristretto;
|
||||||
use crate::ristretto::ristretto_mul;
|
use crate::ristretto::ristretto_mul;
|
||||||
use curve25519_dalek::{constants::RISTRETTO_BASEPOINT_POINT, scalar::Scalar};
|
use curve25519_dalek::{constants::RISTRETTO_BASEPOINT_POINT, scalar::Scalar};
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, info, pubkey::Pubkey,
|
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, msg, pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn test_ristretto_mul() -> ProgramResult {
|
fn test_ristretto_mul() -> ProgramResult {
|
||||||
|
@ -28,7 +28,7 @@ fn process_instruction(
|
||||||
_accounts: &[AccountInfo],
|
_accounts: &[AccountInfo],
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("Ristretto multiply");
|
msg!("Ristretto multiply");
|
||||||
|
|
||||||
test_ristretto_mul()?;
|
test_ristretto_mul()?;
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
account_info::AccountInfo, bpf_loader, entrypoint, entrypoint::ProgramResult, info, log::*,
|
account_info::AccountInfo, bpf_loader, entrypoint, entrypoint::ProgramResult, log::*, msg,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ fn process_instruction(
|
||||||
accounts: &[AccountInfo],
|
accounts: &[AccountInfo],
|
||||||
instruction_data: &[u8],
|
instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
info!("Program identifier:");
|
msg!("Program identifier:");
|
||||||
program_id.log();
|
program_id.log();
|
||||||
|
|
||||||
assert!(!bpf_loader::check_id(program_id));
|
assert!(!bpf_loader::check_id(program_id));
|
||||||
|
@ -34,7 +34,7 @@ fn process_instruction(
|
||||||
// Log the provided account keys and instruction input data. In the case of
|
// 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
|
// 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.
|
// programs will have specific requirements so they can do their work.
|
||||||
info!("Account keys and instruction input data:");
|
msg!("Account keys and instruction input data:");
|
||||||
sol_log_params(accounts, instruction_data);
|
sol_log_params(accounts, instruction_data);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@ fn process_instruction(
|
||||||
let result_str = std::str::from_utf8(&sparkle_heart).unwrap();
|
let result_str = std::str::from_utf8(&sparkle_heart).unwrap();
|
||||||
assert_eq!(4, result_str.len());
|
assert_eq!(4, result_str.len());
|
||||||
assert_eq!("💖", result_str);
|
assert_eq!("💖", result_str);
|
||||||
info!(result_str);
|
msg!(result_str);
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
extern crate solana_program;
|
extern crate solana_program;
|
||||||
use solana_program::{
|
use solana_program::{
|
||||||
hash::{hashv, Hasher},
|
hash::{hashv, Hasher},
|
||||||
info,
|
msg,
|
||||||
};
|
};
|
||||||
|
|
||||||
fn test_hasher() {
|
fn test_hasher() {
|
||||||
|
@ -15,7 +15,7 @@ fn test_hasher() {
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
pub extern "C" fn entrypoint(_input: *mut u8) -> u64 {
|
||||||
info!("sha256");
|
msg!("sha256");
|
||||||
|
|
||||||
test_hasher();
|
test_hasher();
|
||||||
|
|
||||||
|
|
|
@ -2,8 +2,8 @@ use solana_program::{
|
||||||
account_info::AccountInfo,
|
account_info::AccountInfo,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
entrypoint::ProgramResult,
|
entrypoint::ProgramResult,
|
||||||
info,
|
|
||||||
instruction::{AccountMeta, Instruction},
|
instruction::{AccountMeta, Instruction},
|
||||||
|
msg,
|
||||||
program::invoke,
|
program::invoke,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
system_instruction::SystemInstruction,
|
system_instruction::SystemInstruction,
|
||||||
|
@ -42,7 +42,7 @@ fn process_instruction(
|
||||||
account_metas,
|
account_metas,
|
||||||
);
|
);
|
||||||
|
|
||||||
info!("swapped owner and data");
|
msg!("swapped owner and data");
|
||||||
invoke(&ix, &[target.clone(), me.clone(), new_system])?;
|
invoke(&ix, &[target.clone(), me.clone(), new_system])?;
|
||||||
|
|
||||||
let owner_addr = accounts[0].owner as *const Pubkey;
|
let owner_addr = accounts[0].owner as *const Pubkey;
|
||||||
|
|
|
@ -6,7 +6,7 @@ use solana_program::{
|
||||||
clock::DEFAULT_SLOTS_PER_EPOCH,
|
clock::DEFAULT_SLOTS_PER_EPOCH,
|
||||||
entrypoint,
|
entrypoint,
|
||||||
entrypoint::ProgramResult,
|
entrypoint::ProgramResult,
|
||||||
info,
|
msg,
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
rent,
|
rent,
|
||||||
sysvar::{
|
sysvar::{
|
||||||
|
@ -22,26 +22,26 @@ fn process_instruction(
|
||||||
_instruction_data: &[u8],
|
_instruction_data: &[u8],
|
||||||
) -> ProgramResult {
|
) -> ProgramResult {
|
||||||
// Clock
|
// Clock
|
||||||
info!("Clock identifier:");
|
msg!("Clock identifier:");
|
||||||
sysvar::clock::id().log();
|
sysvar::clock::id().log();
|
||||||
let clock = Clock::from_account_info(&accounts[2]).expect("clock");
|
let clock = Clock::from_account_info(&accounts[2]).expect("clock");
|
||||||
assert_eq!(clock.slot, DEFAULT_SLOTS_PER_EPOCH + 1);
|
assert_eq!(clock.slot, DEFAULT_SLOTS_PER_EPOCH + 1);
|
||||||
|
|
||||||
// Fees
|
// Fees
|
||||||
info!("Fees identifier:");
|
msg!("Fees identifier:");
|
||||||
sysvar::fees::id().log();
|
sysvar::fees::id().log();
|
||||||
let fees = Fees::from_account_info(&accounts[3]).expect("fees");
|
let fees = Fees::from_account_info(&accounts[3]).expect("fees");
|
||||||
let fee_calculator = fees.fee_calculator;
|
let fee_calculator = fees.fee_calculator;
|
||||||
assert_eq!(fee_calculator.lamports_per_signature, 0);
|
assert_eq!(fee_calculator.lamports_per_signature, 0);
|
||||||
|
|
||||||
// Slot Hashes
|
// Slot Hashes
|
||||||
info!("SlotHashes identifier:");
|
msg!("SlotHashes identifier:");
|
||||||
sysvar::slot_hashes::id().log();
|
sysvar::slot_hashes::id().log();
|
||||||
let slot_hashes = SlotHashes::from_account_info(&accounts[4]).expect("slot_hashes");
|
let slot_hashes = SlotHashes::from_account_info(&accounts[4]).expect("slot_hashes");
|
||||||
assert!(slot_hashes.len() >= 1);
|
assert!(slot_hashes.len() >= 1);
|
||||||
|
|
||||||
// Stake History
|
// Stake History
|
||||||
info!("StakeHistory identifier:");
|
msg!("StakeHistory identifier:");
|
||||||
sysvar::stake_history::id().log();
|
sysvar::stake_history::id().log();
|
||||||
let stake_history = StakeHistory::from_account_info(&accounts[5]).expect("stake_history");
|
let stake_history = StakeHistory::from_account_info(&accounts[5]).expect("stake_history");
|
||||||
assert!(stake_history.len() >= 1);
|
assert!(stake_history.len() >= 1);
|
||||||
|
|
|
@ -2,11 +2,8 @@
|
||||||
|
|
||||||
use crate::account_info::AccountInfo;
|
use crate::account_info::AccountInfo;
|
||||||
|
|
||||||
/// Prints a string
|
|
||||||
/// There are two forms and are fast
|
|
||||||
/// 1. Single string
|
|
||||||
/// 2. 5 integers
|
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
|
#[deprecated(since = "1.4.14", note = "use `msg` macro instead")]
|
||||||
macro_rules! info {
|
macro_rules! info {
|
||||||
($msg:expr) => {
|
($msg:expr) => {
|
||||||
$crate::log::sol_log($msg)
|
$crate::log::sol_log($msg)
|
||||||
|
@ -19,12 +16,37 @@ macro_rules! info {
|
||||||
$arg4 as u64,
|
$arg4 as u64,
|
||||||
$arg5 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
|
/// Print a message to the log
|
||||||
|
///
|
||||||
|
/// There are two fast forms:
|
||||||
|
/// 1. Single string: `msg!("hi")`
|
||||||
|
/// 2. 5 integers: `msg!(1, 2, 3, 4, 5)`
|
||||||
|
///
|
||||||
|
/// The third form is more generic and incurs a very large runtime overhead so it should be used
|
||||||
|
/// with care:
|
||||||
|
/// 3. Generalized format string: `msg!("Hello {}: 1, 2, {}", "World", 3)`
|
||||||
|
///
|
||||||
|
#[macro_export]
|
||||||
|
macro_rules! msg {
|
||||||
|
($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,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
($($arg:tt)*) => ($crate::log::sol_log(&format!($($arg)*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Print a string to the log
|
||||||
///
|
///
|
||||||
/// @param message - Message to print
|
/// @param message - Message to print
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -43,7 +65,7 @@ extern "C" {
|
||||||
fn sol_log_(message: *const u8, len: u64);
|
fn sol_log_(message: *const u8, len: u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints 64 bit values represented as hexadecimal to stdout
|
/// Print 64-bit values represented as hexadecimal to the log
|
||||||
///
|
///
|
||||||
/// @param argx - integer arguments to print
|
/// @param argx - integer arguments to print
|
||||||
|
|
||||||
|
@ -63,41 +85,41 @@ extern "C" {
|
||||||
fn sol_log_64_(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64);
|
fn sol_log_64_(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints the hexadecimal representation of a slice
|
/// Print the hexadecimal representation of a slice
|
||||||
///
|
///
|
||||||
/// @param slice - The array to print
|
/// @param slice - The array to print
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn sol_log_slice(slice: &[u8]) {
|
pub fn sol_log_slice(slice: &[u8]) {
|
||||||
for (i, s) in slice.iter().enumerate() {
|
for (i, s) in slice.iter().enumerate() {
|
||||||
info!(0, 0, 0, i, *s);
|
msg!(0, 0, 0, i, *s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints the hexadecimal representation of the program's input parameters
|
/// Print the hexadecimal representation of the program's input parameters
|
||||||
///
|
///
|
||||||
/// @param ka - A pointer to an array of `AccountInfo` to print
|
/// @param ka - A pointer to an array of `AccountInfo` to print
|
||||||
/// @param data - A pointer to the instruction data to print
|
/// @param data - A pointer to the instruction data to print
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn sol_log_params(accounts: &[AccountInfo], data: &[u8]) {
|
pub fn sol_log_params(accounts: &[AccountInfo], data: &[u8]) {
|
||||||
for (i, account) in accounts.iter().enumerate() {
|
for (i, account) in accounts.iter().enumerate() {
|
||||||
info!("AccountInfo");
|
msg!("AccountInfo");
|
||||||
info!(0, 0, 0, 0, i);
|
msg!(0, 0, 0, 0, i);
|
||||||
info!("- Is signer");
|
msg!("- Is signer");
|
||||||
info!(0, 0, 0, 0, account.is_signer);
|
msg!(0, 0, 0, 0, account.is_signer);
|
||||||
info!("- Key");
|
msg!("- Key");
|
||||||
account.key.log();
|
account.key.log();
|
||||||
info!("- Lamports");
|
msg!("- Lamports");
|
||||||
info!(0, 0, 0, 0, account.lamports());
|
msg!(0, 0, 0, 0, account.lamports());
|
||||||
info!("- Account data length");
|
msg!("- Account data length");
|
||||||
info!(0, 0, 0, 0, account.data_len());
|
msg!(0, 0, 0, 0, account.data_len());
|
||||||
info!("- Owner");
|
msg!("- Owner");
|
||||||
account.owner.log();
|
account.owner.log();
|
||||||
}
|
}
|
||||||
info!("Instruction data");
|
msg!("Instruction data");
|
||||||
sol_log_slice(data);
|
sol_log_slice(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logs the remaining compute units the program may consume
|
/// Print the remaining compute units the program may consume
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn sol_log_compute_units() {
|
pub fn sol_log_compute_units() {
|
||||||
#[cfg(target_arch = "bpf")]
|
#[cfg(target_arch = "bpf")]
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
use crate::info;
|
use crate::{decode_error::DecodeError, instruction::InstructionError, msg, pubkey::PubkeyError};
|
||||||
use crate::{decode_error::DecodeError, instruction::InstructionError, pubkey::PubkeyError};
|
|
||||||
use num_traits::{FromPrimitive, ToPrimitive};
|
use num_traits::{FromPrimitive, ToPrimitive};
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
@ -56,22 +55,22 @@ impl PrintProgramError for ProgramError {
|
||||||
if let Some(custom_error) = E::decode_custom_error_to_enum(*error) {
|
if let Some(custom_error) = E::decode_custom_error_to_enum(*error) {
|
||||||
custom_error.print::<E>();
|
custom_error.print::<E>();
|
||||||
} else {
|
} else {
|
||||||
info!("Error: Unknown");
|
msg!("Error: Unknown");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Self::InvalidArgument => info!("Error: InvalidArgument"),
|
Self::InvalidArgument => msg!("Error: InvalidArgument"),
|
||||||
Self::InvalidInstructionData => info!("Error: InvalidInstructionData"),
|
Self::InvalidInstructionData => msg!("Error: InvalidInstructionData"),
|
||||||
Self::InvalidAccountData => info!("Error: InvalidAccountData"),
|
Self::InvalidAccountData => msg!("Error: InvalidAccountData"),
|
||||||
Self::AccountDataTooSmall => info!("Error: AccountDataTooSmall"),
|
Self::AccountDataTooSmall => msg!("Error: AccountDataTooSmall"),
|
||||||
Self::InsufficientFunds => info!("Error: InsufficientFunds"),
|
Self::InsufficientFunds => msg!("Error: InsufficientFunds"),
|
||||||
Self::IncorrectProgramId => info!("Error: IncorrectProgramId"),
|
Self::IncorrectProgramId => msg!("Error: IncorrectProgramId"),
|
||||||
Self::MissingRequiredSignature => info!("Error: MissingRequiredSignature"),
|
Self::MissingRequiredSignature => msg!("Error: MissingRequiredSignature"),
|
||||||
Self::AccountAlreadyInitialized => info!("Error: AccountAlreadyInitialized"),
|
Self::AccountAlreadyInitialized => msg!("Error: AccountAlreadyInitialized"),
|
||||||
Self::UninitializedAccount => info!("Error: UninitializedAccount"),
|
Self::UninitializedAccount => msg!("Error: UninitializedAccount"),
|
||||||
Self::NotEnoughAccountKeys => info!("Error: NotEnoughAccountKeys"),
|
Self::NotEnoughAccountKeys => msg!("Error: NotEnoughAccountKeys"),
|
||||||
Self::AccountBorrowFailed => info!("Error: AccountBorrowFailed"),
|
Self::AccountBorrowFailed => msg!("Error: AccountBorrowFailed"),
|
||||||
Self::MaxSeedLengthExceeded => info!("Error: MaxSeedLengthExceeded"),
|
Self::MaxSeedLengthExceeded => msg!("Error: MaxSeedLengthExceeded"),
|
||||||
Self::InvalidSeeds => info!("Error: InvalidSeeds"),
|
Self::InvalidSeeds => msg!("Error: InvalidSeeds"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue