'How to get the current time in Solana program without using any external SystemProgram account

I am writing this Solana program without using Anchor. I want the program to know the current timestamp without using any external SystemProgram.

This is the current version of my program:

use solana_program::{
    account_info::AccountInfo,
    entrypoint,
    entrypoint::ProgramResult,
    msg,
    pubkey::Pubkey,
    sysvar,
};

entrypoint!(process_instruction);


fn process_instruction(
    program_id: &Pubkey,
    accounts: &[AccountInfo],
    instruction_data: &[u8]
) -> ProgramResult {
    msg!("Hello Solana! (From Rust)");
    let nowtime = sysvar::clock::Clock.unix_timestamp;
    Ok(())
}

However, I'm getting this error:

expected value, found struct `sysvar::clock::Clock

How am I supposed to use this sysvar variable?



Solution 1:[1]

You should be able to get the time within a program with the following:

use borsh::{BorshDeserialize, BorshSerialize};
use solana_program::{
    account_info::{next_account_info, AccountInfo},
    clock::Clock,
    entrypoint,
    entrypoint::ProgramResult,
    msg,
    pubkey::Pubkey,
    sysvar::Sysvar,
};

entrypoint!(process_instruction);

#[derive(BorshSerialize, BorshDeserialize, Debug)]
pub struct HelloState {
    is_initialized: bool,
}

// Accounts required
/// 1. [signer, writable] Payer
/// 2. [writable] Hello state account
pub fn process_instruction(
    _program_id: &Pubkey,
    accounts: &[AccountInfo],
    _instruction_data: &[u8],
) -> ProgramResult {
    let accounts_iter = &mut accounts.iter();
    // Payer account
    let _payer_account = next_account_info(accounts_iter)?;
    // Hello state account
    let hello_state_account = next_account_info(accounts_iter)?;

    // Getting clock directly
    let clock = Clock::get()?;

    let mut hello_state = HelloState::try_from_slice(&hello_state_account.data.borrow())?;
    hello_state.is_initialized = true;
    hello_state.serialize(&mut &mut hello_state_account.data.borrow_mut()[..])?;
    msg!("Account initialized :)");

    // Getting timestamp
    let current_timestamp = clock.unix_timestamp;
    msg!("Current Timestamp: {}", current_timestamp);

    Ok(())
}

More specifically

let clock = Clock::get()?;
let current_timestamp = clock.unix_timestamp;

Note: The time on-chain is an estimation. The only reliable clock is slot number on chain. You can read more implementations for getting time here.

Solution 2:[2]

You can get the solana time by following function.

use anchor_lang::{prelude::*, solana_program::clock};
use std::convert::TryInto;

pub fn now_ts() -> Result<u64> {
    Ok(clock::Clock::get()?.unix_timestamp.try_into().unwrap())
}

Solution 3:[3]

Seems like guava cache is implementing ConcurrentMap api

class LocalCache<K, V> extends AbstractMap<K, V> implements ConcurrentMap<K, V> 

so the base get and put operations should be thread safe by nature

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Jacob Creech
Solution 2 John.P
Solution 3 RazBenya