coral-xyz / anchor

⚓ Solana Sealevel Framework
https://anchor-lang.com
Apache License 2.0
3.68k stars 1.35k forks source link

How to forward in time? #657

Open AuroraLantean opened 3 years ago

AuroraLantean commented 3 years ago

During my Anchor tests, I need to simulate certain time change for my Solana program to react differently, such that the time_now below in my Solana program should change:

use solana_program::sysvar::clock::Clock;
let time_now = Clock::get().unwrap().unix_timestamp;

can I do that?

fanatid commented 3 years ago

It's possible with https://crates.io/crates/solana-program-test

AuroraLantean commented 3 years ago

Hi could you explain a little ? I looked it up and found nothing / did not know where it is.

AuroraLantean commented 3 years ago

but I still need an Anchor solution for this...

Arrowana commented 3 years ago

It's possible with https://crates.io/crates/solana-program-test

Unfortunately no, warp_to_slot forwards the slot, but I am pretty sure it does not update the Clock sysvar, this can almost be considered as a bug

but I still need an Anchor solution for this...

We need this feature at the solana-test-validator level, that isn't really possible until this binary can do it. What i do is set a reasonable time expection in anchor test setup, then i just wait until getBlock tells me enough time has passed

fanatid commented 3 years ago

Clock sysvar is changed with warp_to_slot

Arrowana commented 3 years ago

Clock sysvar is changed with warp_to_slot

Oh weird, it actually does

let clock = deserialize::<Clock>(
        &context
            .banks_client
            .get_account(sysvar::clock::ID)
            .await
            .unwrap()
            .unwrap()
            .data,
    )
    .unwrap();
  println!("slot: {}, unix_timestamp: {}", clock.slot, clock.unix_timestamp);
  context.warp_to_slot(10_000)
      .unwrap();
      let clock = deserialize::<Clock>(
          &context
              .banks_client
              .get_account(sysvar::clock::ID)
              .await
              .unwrap()
              .unwrap()
              .data,
      )
      .unwrap();
  println!("slot: {}, unix_timestamp: {}", clock.slot, clock.unix_timestamp);

The output of this code is slot: 1, unix_timestamp: 1631752976 slot: 10000, unix_timestamp: 1631753528

I said no because this chat said the clock syvar wouldn't move, i cannot find a commit that says it got implemented, so maybe it has been working the entire time: https://discordapp.com/channels/428295358100013066/758929221061050378/854394968084840509

For solana-test-validator, it seems like we need to be able to advanced slots in the same way: https://github.com/solana-labs/solana/issues/19005