I am working on the Solana contract with rust language and faced one critical problem.
In order to get current Unix timestamp, I used SystemTime
like below.
let current_timestamp: i64 = SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap()
.as_secs() as i64;
Btw, the client asking to not to use SystemTime
because it waste too many compute unit.
For this problem, I used BpfClock
but it doesn't pass the unit test.
let clock = BpfClock::get()?;
let current_timestamp: i64 = clock.unix_timestamp;
The unit test result below error message:
thread 'processor::tests::test_withdraw' panicked at 'called `Result::unwrap()` on an `Err` value: UnsupportedSysvar'
This is expected behavior. On-chain, you do not have access to the system time, only utilities that are exposed by the runtime, so SystemTime::now()
will completely fail on-chain. You can read more about these restrictions at https://docs.solana.com/developing/on-chain-programs/developing-rust#restrictions
To access the clock, you are doing the right thing, but you must be runing in some sort of runtime-like environment for this to work. This could be fully on-chain or through solana_program_test
, which gives access to utilities such as Clock
. You can see a working example of using the Clock on-chain at https://github.com/solana-labs/solana-program-library/tree/master/examples/rust/sysvar
Be sure to run the tests using cargo test-bpf
from the Solana CLI -- you can find the installation instructions at https://docs.solana.com/cli/install-solana-cli-tools