Proposal: log binary data for Solidity

Rename "Program return data: " to "Program return: " since "data" is
redundant.

(cherry picked from commit b89177c8de)

Conflicts:
	programs/bpf_loader/src/syscalls.rs
	sdk/bpf/c/inc/sol/log.h
	sdk/program/Cargo.toml
	sdk/src/feature_set.rs
	sdk/src/process_instruction.rs
This commit is contained in:
Sean Young
2021-09-17 09:14:49 +01:00
parent 400a88786a
commit ebe77a0985
17 changed files with 429 additions and 8 deletions

View File

@@ -2869,6 +2869,13 @@ dependencies = [
"solana-program 1.8.1",
]
[[package]]
name = "solana-bpf-rust-log-data"
version = "1.8.1"
dependencies = [
"solana-program 1.8.1",
]
[[package]]
name = "solana-bpf-rust-many-args"
version = "1.8.1"
@@ -3316,6 +3323,7 @@ dependencies = [
name = "solana-program"
version = "1.8.1"
dependencies = [
"base64 0.13.0",
"bincode",
"blake3",
"borsh",

View File

@@ -52,6 +52,7 @@ members = [
"rust/deprecated_loader",
"rust/dup_accounts",
"rust/error_handling",
"rust/log_data",
"rust/external_spend",
"rust/finalize",
"rust/instruction_introspection",

View File

@@ -67,6 +67,7 @@ fn main() {
"deprecated_loader",
"dup_accounts",
"error_handling",
"log_data",
"external_spend",
"finalize",
"instruction_introspection",

View File

@@ -0,0 +1,28 @@
/**
* @brief Example C-based BPF program uses sol_log_data
*/
#include <solana_sdk.h>
static const uint8_t return_data[] = { 0x08, 0x01, 0x44 };
extern uint64_t entrypoint(const uint8_t *input) {
SolAccountInfo ka[1];
SolParameters params = (SolParameters) { .ka = ka };
SolBytes fields[2];
if (!sol_deserialize(input, &params, SOL_ARRAY_SIZE(ka))) {
return ERROR_INVALID_ARGUMENT;
}
// Generate two fields, split at the first 0 in the input
fields[0].addr = params.data;
fields[0].len = sol_strlen((char*)fields[0].addr);
fields[1].addr = fields[0].addr + fields[0].len + 1;
fields[1].len = params.data_len - fields[0].len - 1;
sol_set_return_data(return_data, sizeof(return_data));
sol_log_data(fields, 2);
return SUCCESS;
}

View File

@@ -0,0 +1,23 @@
[package]
name = "solana-bpf-rust-log-data"
version = "1.8.1"
description = "Solana BPF test program written in Rust"
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
repository = "https://github.com/solana-labs/solana"
license = "Apache-2.0"
homepage = "https://solana.com/"
documentation = "https://docs.rs/solana-bpf-rust-log-data"
edition = "2018"
[dependencies]
solana-program = { path = "../../../../sdk/program", version = "=1.8.1" }
[features]
default = ["program"]
program = []
[lib]
crate-type = ["lib", "cdylib"]
[package.metadata.docs.rs]
targets = ["x86_64-unknown-linux-gnu"]

View File

@@ -0,0 +1,24 @@
//! @brief Example Rust-based BPF program that uses sol_log_data syscall
#![cfg(feature = "program")]
use solana_program::{
account_info::AccountInfo, entrypoint, entrypoint::ProgramResult, log::sol_log_data,
program::set_return_data, pubkey::Pubkey,
};
entrypoint!(process_instruction);
#[allow(clippy::cognitive_complexity)]
fn process_instruction(
_program_id: &Pubkey,
_accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let fields: Vec<&[u8]> = instruction_data.split(|e| *e == 0).collect();
set_return_data(&[0x08, 0x01, 0x44]);
sol_log_data(&fields);
Ok(())
}

View File

@@ -736,6 +736,55 @@ fn test_program_bpf_error_handling() {
}
}
#[test]
#[cfg(any(feature = "bpf_c", feature = "bpf_rust"))]
fn test_return_data_and_log_data_syscall() {
solana_logger::setup();
let mut programs = Vec::new();
#[cfg(feature = "bpf_c")]
{
programs.extend_from_slice(&[("log_data")]);
}
#[cfg(feature = "bpf_rust")]
{
programs.extend_from_slice(&[("solana_bpf_rust_log_data")]);
}
for program in programs.iter() {
let GenesisConfigInfo {
genesis_config,
mint_keypair,
..
} = create_genesis_config(50);
let mut bank = Bank::new(&genesis_config);
let (name, id, entrypoint) = solana_bpf_loader_program!();
bank.add_builtin(&name, id, entrypoint);
let bank = Arc::new(bank);
let bank_client = BankClient::new_shared(&bank);
let program_id = load_bpf_program(&bank_client, &bpf_loader::id(), &mint_keypair, program);
bank.freeze();
let account_metas = vec![AccountMeta::new(mint_keypair.pubkey(), true)];
let instruction =
Instruction::new_with_bytes(program_id, &[1, 2, 3, 0, 4, 5, 6], account_metas);
let blockhash = bank.last_blockhash();
let message = Message::new(&[instruction], Some(&mint_keypair.pubkey()));
let transaction = Transaction::new(&[&mint_keypair], message, blockhash);
let (result, logs, _) = bank.simulate_transaction(&transaction);
assert!(result.is_ok());
assert_eq!(logs[1], "Program data: AQID BAUG");
assert_eq!(logs[3], format!("Program return: {} CAFE", program_id));
}
}
#[test]
fn test_program_bpf_invoke_sanity() {
solana_logger::setup();