Search code examples
smartcontractsscrypto

How to change ledger's epoch during unit test?


I am trying to change epoch in a single unit test:

  1. I run a method
  2. I switch to next epoch
  3. I run another method (on the same substate store)

It seems like I can not mutate substate store's epoch if I use a TransactionExecutor on it:

use radix_engine::ledger::*;
use radix_engine::transaction::*;
use scrypto::prelude::*;

#[test]
fn can_tick_from_scratch() {
    let mut ledger = InMemorySubstateStore::with_bootstrap();

    ledger.set_epoch(15);

    let mut executor = TransactionExecutor::new(&mut ledger, false);

    // Run transactions
    // ...

    ledger.set_epoch(16);

    // Run other transactions
    // ...
}
error[E0499]: cannot borrow `ledger` as mutable more than once at a time
  --> tests/lib.rs:16:5
   |
11 |     let mut executor = TransactionExecutor::new(&mut ledger, false);
   |                                                 ----------- first mutable borrow occurs here ...
16 |     ledger.set_epoch(16);
   |     ^^^^^^^^^^^^^^^^^^^^ second mutable borrow occurs here
17 | 
18 |     let (pk, sk, oracle_owner) = executor.new_account();
   |                                  ---------------------- first borrow later used here

How can I change the epoch of the InMemorySubstateStore passed to the TransactionExecutor?


Solution

  • You indeed can not mutate the InMemorySubstateStore variable directly after passing it to the TransactionExecutor. What you want to do is to change the executor's substate_store state:

    use radix_engine::ledger::*;
    use radix_engine::transaction::*;
    use scrypto::prelude::*;
    
    #[test]
    fn can_tick_from_scratch() {
        let mut ledger = InMemorySubstateStore::with_bootstrap();
    
        ledger.set_epoch(15);
    
        let mut executor = TransactionExecutor::new(&mut ledger, false);
    
        // Run transactions
        // ...
    
        executor.substate_store_mut().set_epoch(16);
    
        // Run other transactions
        // ...
    }