program log pubkey as base58 (#12901)
This commit is contained in:
parent
b1b2c6ee7b
commit
3f9e6a600b
|
@ -229,8 +229,7 @@ fn bench_instruction_count_tuner(_bencher: &mut Bencher) {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let r = vm.execute_program_metered(&mut serialized, &[], &[], instruction_meter.clone());
|
let _ = vm.execute_program_metered(&mut serialized, &[], &[], instruction_meter.clone()); measure.stop();
|
||||||
measure.stop();
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
0,
|
0,
|
||||||
instruction_meter.get_remaining(),
|
instruction_meter.get_remaining(),
|
||||||
|
|
|
@ -12,9 +12,9 @@
|
||||||
|
|
||||||
extern uint64_t entrypoint(const uint8_t *input) {
|
extern uint64_t entrypoint(const uint8_t *input) {
|
||||||
SolAccountInfo ka[NUM_KA];
|
SolAccountInfo ka[NUM_KA];
|
||||||
SolParameters params = (SolParameters) { .ka = ka };
|
SolParameters params = (SolParameters){.ka = ka};
|
||||||
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(ka))) {
|
if (!sol_deserialize(input, ¶ms, SOL_ARRAY_SIZE(ka))) {
|
||||||
return ERROR_INVALID_ARGUMENT;
|
return ERROR_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
uint8_t *val = (uint8_t *)ka[0].data;
|
uint8_t *val = (uint8_t *)ka[0].data;
|
||||||
size_t current = 1;
|
size_t current = 1;
|
||||||
|
@ -35,6 +35,12 @@ extern uint64_t entrypoint(const uint8_t *input) {
|
||||||
// sol_sha256(bytes, SOL_ARRAY_SIZE(bytes), result);
|
// sol_sha256(bytes, SOL_ARRAY_SIZE(bytes), result);
|
||||||
// *val = result[0];
|
// *val = result[0];
|
||||||
// }
|
// }
|
||||||
|
|
||||||
|
// // Uncomment for Pubkey logging syscall
|
||||||
|
// {
|
||||||
|
// SolPubkey pubkey;
|
||||||
|
// sol_log_pubkey(&pubkey);
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
return *val;
|
return *val;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,6 @@ use solana_sdk::{
|
||||||
entrypoint,
|
entrypoint,
|
||||||
entrypoint::ProgramResult,
|
entrypoint::ProgramResult,
|
||||||
info,
|
info,
|
||||||
log::Log,
|
|
||||||
pubkey::Pubkey,
|
pubkey::Pubkey,
|
||||||
rent,
|
rent,
|
||||||
sysvar::{
|
sysvar::{
|
||||||
|
|
|
@ -612,6 +612,7 @@ mod tests {
|
||||||
sha256_byte_cost: 1,
|
sha256_byte_cost: 1,
|
||||||
max_call_depth: 20,
|
max_call_depth: 20,
|
||||||
stack_frame_size: 4096,
|
stack_frame_size: 4096,
|
||||||
|
log_pubkey_units: 100,
|
||||||
},
|
},
|
||||||
Rc::new(RefCell::new(Executors::default())),
|
Rc::new(RefCell::new(Executors::default())),
|
||||||
None,
|
None,
|
||||||
|
|
|
@ -8,7 +8,9 @@ use solana_rbpf::{
|
||||||
vm::{EbpfVm, SyscallObject},
|
vm::{EbpfVm, SyscallObject},
|
||||||
};
|
};
|
||||||
use solana_runtime::{
|
use solana_runtime::{
|
||||||
feature_set::{ristretto_mul_syscall_enabled, sha256_syscall_enabled},
|
feature_set::{
|
||||||
|
pubkey_log_syscall_enabled, ristretto_mul_syscall_enabled, sha256_syscall_enabled,
|
||||||
|
},
|
||||||
message_processor::MessageProcessor,
|
message_processor::MessageProcessor,
|
||||||
process_instruction::{ComputeMeter, InvokeContext, Logger},
|
process_instruction::{ComputeMeter, InvokeContext, Logger},
|
||||||
};
|
};
|
||||||
|
@ -120,6 +122,18 @@ pub fn register_syscalls<'a>(
|
||||||
}),
|
}),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
if invoke_context.is_feature_active(&pubkey_log_syscall_enabled::id()) {
|
||||||
|
vm.register_syscall_with_context_ex(
|
||||||
|
"sol_log_pubkey",
|
||||||
|
Box::new(SyscallLogPubkey {
|
||||||
|
cost: compute_budget.log_pubkey_units,
|
||||||
|
compute_meter: invoke_context.get_compute_meter(),
|
||||||
|
logger: invoke_context.get_logger(),
|
||||||
|
loader_id,
|
||||||
|
}),
|
||||||
|
)?;
|
||||||
|
}
|
||||||
|
|
||||||
if invoke_context.is_feature_active(&sha256_syscall_enabled::id()) {
|
if invoke_context.is_feature_active(&sha256_syscall_enabled::id()) {
|
||||||
vm.register_syscall_with_context_ex(
|
vm.register_syscall_with_context_ex(
|
||||||
"sol_sha256",
|
"sol_sha256",
|
||||||
|
@ -400,6 +414,37 @@ impl SyscallObject<BPFError> for SyscallLogU64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Log 5 64-bit values
|
||||||
|
pub struct SyscallLogPubkey<'a> {
|
||||||
|
cost: u64,
|
||||||
|
compute_meter: Rc<RefCell<dyn ComputeMeter>>,
|
||||||
|
logger: Rc<RefCell<dyn Logger>>,
|
||||||
|
loader_id: &'a Pubkey,
|
||||||
|
}
|
||||||
|
impl<'a> SyscallObject<BPFError> for SyscallLogPubkey<'a> {
|
||||||
|
fn call(
|
||||||
|
&mut self,
|
||||||
|
pubkey_addr: u64,
|
||||||
|
_arg2: u64,
|
||||||
|
_arg3: u64,
|
||||||
|
_arg4: u64,
|
||||||
|
_arg5: u64,
|
||||||
|
ro_regions: &[MemoryRegion],
|
||||||
|
_rw_regions: &[MemoryRegion],
|
||||||
|
) -> Result<u64, EbpfError<BPFError>> {
|
||||||
|
self.compute_meter.consume(self.cost)?;
|
||||||
|
let mut logger = self
|
||||||
|
.logger
|
||||||
|
.try_borrow_mut()
|
||||||
|
.map_err(|_| SyscallError::InvokeContextBorrowFailed)?;
|
||||||
|
if logger.log_enabled() {
|
||||||
|
let pubkey = translate_type!(Pubkey, pubkey_addr, ro_regions, self.loader_id)?;
|
||||||
|
logger.log(&format!("Program log: {}", pubkey));
|
||||||
|
}
|
||||||
|
Ok(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Dynamic memory allocation syscall called when the BPF program calls
|
/// Dynamic memory allocation syscall called when the BPF program calls
|
||||||
/// `sol_alloc_free_()`. The allocator is expected to allocate/free
|
/// `sol_alloc_free_()`. The allocator is expected to allocate/free
|
||||||
/// from/to a given chunk of memory and enforce size restrictions. The
|
/// from/to a given chunk of memory and enforce size restrictions. The
|
||||||
|
@ -1194,6 +1239,7 @@ mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::tests::{MockComputeMeter, MockLogger};
|
use crate::tests::{MockComputeMeter, MockLogger};
|
||||||
use solana_sdk::hash::hashv;
|
use solana_sdk::hash::hashv;
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
macro_rules! assert_access_violation {
|
macro_rules! assert_access_violation {
|
||||||
($result:expr, $va:expr, $len:expr) => {
|
($result:expr, $va:expr, $len:expr) => {
|
||||||
|
@ -1467,6 +1513,55 @@ mod tests {
|
||||||
assert_eq!(log.borrow()[0], "Program log: 0x1, 0x2, 0x3, 0x4, 0x5");
|
assert_eq!(log.borrow()[0], "Program log: 0x1, 0x2, 0x3, 0x4, 0x5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_syscall_sol_pubkey() {
|
||||||
|
let pubkey = Pubkey::from_str("MoqiU1vryuCGQSxFKA1SZ316JdLEFFhoAu6cKUNk7dN").unwrap();
|
||||||
|
let addr = &pubkey.as_ref()[0] as *const _ as u64;
|
||||||
|
|
||||||
|
let compute_meter: Rc<RefCell<dyn ComputeMeter>> =
|
||||||
|
Rc::new(RefCell::new(MockComputeMeter { remaining: 2 }));
|
||||||
|
let log = Rc::new(RefCell::new(vec![]));
|
||||||
|
let logger: Rc<RefCell<dyn Logger>> =
|
||||||
|
Rc::new(RefCell::new(MockLogger { log: log.clone() }));
|
||||||
|
let mut syscall_sol_pubkey = SyscallLogPubkey {
|
||||||
|
cost: 1,
|
||||||
|
compute_meter,
|
||||||
|
logger,
|
||||||
|
loader_id: &bpf_loader::id(),
|
||||||
|
};
|
||||||
|
let ro_regions = &[MemoryRegion {
|
||||||
|
addr_host: addr,
|
||||||
|
addr_vm: 100,
|
||||||
|
len: 32,
|
||||||
|
}];
|
||||||
|
let rw_regions = &[MemoryRegion::default()];
|
||||||
|
|
||||||
|
syscall_sol_pubkey
|
||||||
|
.call(100, 0, 0, 0, 0, ro_regions, rw_regions)
|
||||||
|
.unwrap();
|
||||||
|
assert_eq!(log.borrow().len(), 1);
|
||||||
|
assert_eq!(
|
||||||
|
log.borrow()[0],
|
||||||
|
"Program log: MoqiU1vryuCGQSxFKA1SZ316JdLEFFhoAu6cKUNk7dN"
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_access_violation!(
|
||||||
|
syscall_sol_pubkey.call(
|
||||||
|
101, // AccessViolation
|
||||||
|
32, 0, 0, 0, ro_regions, rw_regions,
|
||||||
|
),
|
||||||
|
101,
|
||||||
|
32
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
Err(EbpfError::UserError(BPFError::SyscallError(
|
||||||
|
SyscallError::InstructionError(InstructionError::ComputationalBudgetExceeded)
|
||||||
|
))),
|
||||||
|
syscall_sol_pubkey.call(100, 32, 0, 0, 0, ro_regions, rw_regions)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_syscall_sol_alloc_free() {
|
fn test_syscall_sol_alloc_free() {
|
||||||
// large alloc
|
// large alloc
|
||||||
|
|
|
@ -65,6 +65,10 @@ pub mod cumulative_rent_related_fixes {
|
||||||
solana_sdk::declare_id!("FtjnuAtJTWwX3Kx9m24LduNEhzaGuuPfDW6e14SX2Fy5");
|
solana_sdk::declare_id!("FtjnuAtJTWwX3Kx9m24LduNEhzaGuuPfDW6e14SX2Fy5");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod pubkey_log_syscall_enabled {
|
||||||
|
solana_sdk::declare_id!("MoqiU1vryuCGQSxFKA1SZ316JdLEFFhoAu6cKUNk7dN");
|
||||||
|
}
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
/// Map of feature identifiers to user-visible description
|
/// Map of feature identifiers to user-visible description
|
||||||
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
pub static ref FEATURE_NAMES: HashMap<Pubkey, &'static str> = [
|
||||||
|
@ -83,6 +87,7 @@ lazy_static! {
|
||||||
(max_program_call_depth_64::id(), "max program call depth 64"),
|
(max_program_call_depth_64::id(), "max program call depth 64"),
|
||||||
(timestamp_correction::id(), "correct bank timestamps"),
|
(timestamp_correction::id(), "correct bank timestamps"),
|
||||||
(cumulative_rent_related_fixes::id(), "rent fixes (#10206, #10468, #11342)"),
|
(cumulative_rent_related_fixes::id(), "rent fixes (#10206, #10468, #11342)"),
|
||||||
|
(pubkey_log_syscall_enabled::id(), "pubkey log syscall"),
|
||||||
/*************** ADD NEW FEATURES HERE ***************/
|
/*************** ADD NEW FEATURES HERE ***************/
|
||||||
]
|
]
|
||||||
.iter()
|
.iter()
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::feature_set::{
|
use crate::feature_set::{
|
||||||
compute_budget_balancing, max_invoke_depth_4, max_program_call_depth_64, FeatureSet,
|
compute_budget_balancing, max_invoke_depth_4, max_program_call_depth_64,
|
||||||
|
pubkey_log_syscall_enabled, FeatureSet,
|
||||||
};
|
};
|
||||||
use solana_sdk::{
|
use solana_sdk::{
|
||||||
account::{Account, KeyedAccount},
|
account::{Account, KeyedAccount},
|
||||||
|
@ -85,19 +86,21 @@ pub struct ComputeBudget {
|
||||||
pub log_64_units: u64,
|
pub log_64_units: u64,
|
||||||
/// Number of compute units consumed by a create_program_address call
|
/// Number of compute units consumed by a create_program_address call
|
||||||
pub create_program_address_units: u64,
|
pub create_program_address_units: u64,
|
||||||
/// Number of compute units consumed by an invoke call (not including the cost incured by
|
/// Number of compute units consumed by an invoke call (not including the cost incurred by
|
||||||
/// the called program)
|
/// the called program)
|
||||||
pub invoke_units: u64,
|
pub invoke_units: u64,
|
||||||
/// Maximum cross-program invocation depth allowed including the orignal caller
|
/// Maximum cross-program invocation depth allowed including the original caller
|
||||||
pub max_invoke_depth: usize,
|
pub max_invoke_depth: usize,
|
||||||
/// Base number of compute units consumed to call sha256
|
/// Base number of compute units consumed to call SHA256
|
||||||
pub sha256_base_cost: u64,
|
pub sha256_base_cost: u64,
|
||||||
/// Incremental number of units consumed by sha256 (based on bytes)
|
/// Incremental number of units consumed by SHA256 (based on bytes)
|
||||||
pub sha256_byte_cost: u64,
|
pub sha256_byte_cost: u64,
|
||||||
/// Maximum BPF to BPF call depth
|
/// Maximum BPF to BPF call depth
|
||||||
pub max_call_depth: usize,
|
pub max_call_depth: usize,
|
||||||
/// Size of a stack frame in bytes, must match the size specified in the LLVM BPF backend
|
/// Size of a stack frame in bytes, must match the size specified in the LLVM BPF backend
|
||||||
pub stack_frame_size: usize,
|
pub stack_frame_size: usize,
|
||||||
|
/// Number of compute units consumed by logging a `Pubkey`
|
||||||
|
pub log_pubkey_units: u64,
|
||||||
}
|
}
|
||||||
impl Default for ComputeBudget {
|
impl Default for ComputeBudget {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
|
@ -119,6 +122,7 @@ impl ComputeBudget {
|
||||||
sha256_byte_cost: 1,
|
sha256_byte_cost: 1,
|
||||||
max_call_depth: 20,
|
max_call_depth: 20,
|
||||||
stack_frame_size: 4_096,
|
stack_frame_size: 4_096,
|
||||||
|
log_pubkey_units: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
if feature_set.is_active(&compute_budget_balancing::id()) {
|
if feature_set.is_active(&compute_budget_balancing::id()) {
|
||||||
|
@ -144,6 +148,12 @@ impl ComputeBudget {
|
||||||
..compute_budget
|
..compute_budget
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
if feature_set.is_active(&pubkey_log_syscall_enabled::id()) {
|
||||||
|
compute_budget = ComputeBudget {
|
||||||
|
log_pubkey_units: 100,
|
||||||
|
..compute_budget
|
||||||
|
};
|
||||||
|
}
|
||||||
compute_budget
|
compute_budget
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -540,11 +540,9 @@ static uint64_t sol_invoke(
|
||||||
*
|
*
|
||||||
* @param key The public key to print
|
* @param key The public key to print
|
||||||
*/
|
*/
|
||||||
static void sol_log_key(const SolPubkey *key) {
|
void sol_log_pubkey(
|
||||||
for (int j = 0; j < sizeof(*key); j++) {
|
const SolPubkey *pubkey
|
||||||
sol_log_64(0, 0, 0, j, key->x[j]);
|
);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Prints the hexadecimal representation of an array
|
* Prints the hexadecimal representation of an array
|
||||||
|
@ -564,7 +562,7 @@ static void sol_log_array(const uint8_t *array, int len) {
|
||||||
*/
|
*/
|
||||||
static void sol_log_params(const SolParameters *params) {
|
static void sol_log_params(const SolParameters *params) {
|
||||||
sol_log("- Program identifier:");
|
sol_log("- Program identifier:");
|
||||||
sol_log_key(params->program_id);
|
sol_log_pubkey(params->program_id);
|
||||||
|
|
||||||
sol_log("- Number of KeyedAccounts");
|
sol_log("- Number of KeyedAccounts");
|
||||||
sol_log_64(0, 0, 0, 0, params->ka_num);
|
sol_log_64(0, 0, 0, 0, params->ka_num);
|
||||||
|
@ -574,13 +572,13 @@ static void sol_log_params(const SolParameters *params) {
|
||||||
sol_log(" - Is writable");
|
sol_log(" - Is writable");
|
||||||
sol_log_64(0, 0, 0, 0, params->ka[i].is_writable);
|
sol_log_64(0, 0, 0, 0, params->ka[i].is_writable);
|
||||||
sol_log(" - Key");
|
sol_log(" - Key");
|
||||||
sol_log_key(params->ka[i].key);
|
sol_log_pubkey(params->ka[i].key);
|
||||||
sol_log(" - Lamports");
|
sol_log(" - Lamports");
|
||||||
sol_log_64(0, 0, 0, 0, *params->ka[i].lamports);
|
sol_log_64(0, 0, 0, 0, *params->ka[i].lamports);
|
||||||
sol_log(" - data");
|
sol_log(" - data");
|
||||||
sol_log_array(params->ka[i].data, params->ka[i].data_len);
|
sol_log_array(params->ka[i].data, params->ka[i].data_len);
|
||||||
sol_log(" - Owner");
|
sol_log(" - Owner");
|
||||||
sol_log_key(params->ka[i].owner);
|
sol_log_pubkey(params->ka[i].owner);
|
||||||
sol_log(" - Executable");
|
sol_log(" - Executable");
|
||||||
sol_log_64(0, 0, 0, 0, params->ka[i].executable);
|
sol_log_64(0, 0, 0, 0, params->ka[i].executable);
|
||||||
sol_log(" - Rent Epoch");
|
sol_log(" - Rent Epoch");
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
#![cfg(feature = "program")]
|
#![cfg(feature = "program")]
|
||||||
|
|
||||||
use crate::{account_info::AccountInfo, pubkey::Pubkey};
|
use crate::account_info::AccountInfo;
|
||||||
|
|
||||||
/// Prints a string
|
/// Prints a string
|
||||||
/// There are two forms and are fast
|
/// There are two forms and are fast
|
||||||
|
@ -63,18 +63,6 @@ pub fn sol_log_slice(slice: &[u8]) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Prints a pubkey
|
|
||||||
pub trait Log {
|
|
||||||
fn log(&self);
|
|
||||||
}
|
|
||||||
impl Log for Pubkey {
|
|
||||||
fn log(&self) {
|
|
||||||
for (i, k) in self.to_bytes().iter().enumerate() {
|
|
||||||
info!(0, 0, 0, i, *k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Prints the hexadecimal representation of the program's input parameters
|
/// Prints 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
|
||||||
|
|
|
@ -202,9 +202,16 @@ impl Pubkey {
|
||||||
pub fn to_bytes(self) -> [u8; 32] {
|
pub fn to_bytes(self) -> [u8; 32] {
|
||||||
self.0
|
self.0
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// TODO localalize this
|
/// Log a `Pubkey` from a program
|
||||||
|
#[cfg(feature = "program")]
|
||||||
|
pub fn log(&self) {
|
||||||
|
extern "C" {
|
||||||
|
fn sol_log_pubkey(pubkey_addr: *const u8);
|
||||||
|
};
|
||||||
|
unsafe { sol_log_pubkey(self.as_ref() as *const _ as *const u8) };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl AsRef<[u8]> for Pubkey {
|
impl AsRef<[u8]> for Pubkey {
|
||||||
fn as_ref(&self) -> &[u8] {
|
fn as_ref(&self) -> &[u8] {
|
||||||
|
|
Loading…
Reference in New Issue