program log pubkey as base58 (#12901)
This commit is contained in:
		@@ -8,7 +8,9 @@ use solana_rbpf::{
 | 
			
		||||
    vm::{EbpfVm, SyscallObject},
 | 
			
		||||
};
 | 
			
		||||
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,
 | 
			
		||||
    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()) {
 | 
			
		||||
        vm.register_syscall_with_context_ex(
 | 
			
		||||
            "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
 | 
			
		||||
/// `sol_alloc_free_()`.  The allocator is expected to allocate/free
 | 
			
		||||
/// from/to a given chunk of memory and enforce size restrictions.  The
 | 
			
		||||
@@ -1194,6 +1239,7 @@ mod tests {
 | 
			
		||||
    use super::*;
 | 
			
		||||
    use crate::tests::{MockComputeMeter, MockLogger};
 | 
			
		||||
    use solana_sdk::hash::hashv;
 | 
			
		||||
    use std::str::FromStr;
 | 
			
		||||
 | 
			
		||||
    macro_rules! assert_access_violation {
 | 
			
		||||
        ($result:expr, $va:expr, $len:expr) => {
 | 
			
		||||
@@ -1467,6 +1513,55 @@ mod tests {
 | 
			
		||||
        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]
 | 
			
		||||
    fn test_syscall_sol_alloc_free() {
 | 
			
		||||
        // large alloc
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user