Add return data implementation

This consists of:
 - syscalls
 - passing return data from invoked to invoker
 - printing to stable log
 - rust and C SDK changes
This commit is contained in:
Sean Young
2021-09-01 10:14:01 +01:00
parent 2dee098b91
commit 098585234d
23 changed files with 641 additions and 35 deletions

View File

@ -1,4 +1,6 @@
use crate::{account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction};
use crate::{
account_info::AccountInfo, entrypoint::ProgramResult, instruction::Instruction, pubkey::Pubkey,
};
/// Invoke a cross-program instruction
///
@ -35,6 +37,16 @@ pub fn invoke_signed(
#[cfg(target_arch = "bpf")]
{
extern "C" {
fn sol_invoke_signed_rust(
instruction_addr: *const u8,
account_infos_addr: *const u8,
account_infos_len: u64,
signers_seeds_addr: *const u8,
signers_seeds_len: u64,
) -> u64;
}
let result = unsafe {
sol_invoke_signed_rust(
instruction as *const _ as *const u8,
@ -54,13 +66,48 @@ pub fn invoke_signed(
crate::program_stubs::sol_invoke_signed(instruction, account_infos, signers_seeds)
}
#[cfg(target_arch = "bpf")]
extern "C" {
fn sol_invoke_signed_rust(
instruction_addr: *const u8,
account_infos_addr: *const u8,
account_infos_len: u64,
signers_seeds_addr: *const u8,
signers_seeds_len: u64,
) -> u64;
/// Maximum size that can be set using sol_set_return_data()
pub const MAX_RETURN_DATA: usize = 1024;
/// Set a program's return data
pub fn set_return_data(data: &[u8]) {
#[cfg(target_arch = "bpf")]
{
extern "C" {
fn sol_set_return_data(data: *const u8, length: u64);
}
unsafe { sol_set_return_data(data.as_ptr(), data.len() as u64) };
}
#[cfg(not(target_arch = "bpf"))]
crate::program_stubs::sol_set_return_data(data)
}
/// Get the return data from invoked program
pub fn get_return_data() -> Option<(Pubkey, Vec<u8>)> {
#[cfg(target_arch = "bpf")]
{
use std::cmp::min;
extern "C" {
fn sol_get_return_data(data: *mut u8, length: u64, program_id: *mut Pubkey) -> u64;
}
let mut buf = [0u8; MAX_RETURN_DATA];
let mut program_id = Pubkey::default();
let size =
unsafe { sol_get_return_data(buf.as_mut_ptr(), buf.len() as u64, &mut program_id) };
if size == 0 {
None
} else {
let size = min(size as usize, MAX_RETURN_DATA);
Some((program_id, buf[..size as usize].to_vec()))
}
}
#[cfg(not(target_arch = "bpf"))]
crate::program_stubs::sol_get_return_data()
}