Skip to content

Commit

Permalink
Support jumping to future blocks
Browse files Browse the repository at this point in the history
  • Loading branch information
lemunozm committed Oct 26, 2023
1 parent 5b264e0 commit 83a5095
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 16 deletions.
17 changes: 16 additions & 1 deletion runtime/integration-tests/src/generic/cases/example.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use cfg_primitives::{Balance, CFG};
use cfg_primitives::{Balance, CFG, SECONDS_PER_YEAR};
use cfg_traits::IntoSeconds;
use frame_support::traits::Get;
use sp_api::runtime_decl_for_Core::CoreV4;

Expand Down Expand Up @@ -156,7 +157,21 @@ fn fudge_call_api<T: Runtime + FudgeSupport>() {
})
}

fn pass_time_one_block<T: Runtime>() {
let mut env = RuntimeEnv::<T>::from_storage(Default::default());

let before = env.state(|| pallet_timestamp::Pallet::<T>::get());

// Not supported in fudge
env.pass(Blocks::JumpBySeconds(SECONDS_PER_YEAR));

let after = env.state(|| pallet_timestamp::Pallet::<T>::get());

assert_eq!((after - before).into_seconds(), SECONDS_PER_YEAR)
}

crate::test_for_runtimes!([development, altair, centrifuge], transfer_balance);
crate::test_for_runtimes!(all, call_api);
crate::test_for_runtimes!(all, fudge_transfer_balance);
crate::test_for_runtimes!(all, fudge_call_api);
crate::test_for_runtimes!(all, pass_time_one_block);
50 changes: 36 additions & 14 deletions runtime/integration-tests/src/generic/env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,26 +24,37 @@ pub enum Blocks<Event> {

/// Pass a number of block until find an event or reach the limit
UntilEvent { event: Event, limit: BlockNumber },

/// Jumps to a block in the future to reach the requested time.
/// Only one real block is created in the process.
/// This can be used to emulate passing time during long periods
/// computationally very fast.
/// (i.e. years)
JumpBySeconds(Seconds),
}

impl<Event> Blocks<Event> {
fn range_for(&self, current: BlockNumber, slot_duration: Seconds) -> Range<BlockNumber> {
let blocks = match self {
Blocks::ByNumber(n) => *n,
let next = current + 1;
let (from, to) = match self {
Blocks::ByNumber(n) => (next, next + *n),
Blocks::BySeconds(secs) => {
let n = secs / slot_duration;
let mut blocks = (secs / slot_duration) as BlockNumber;
if secs % slot_duration != 0 {
n as BlockNumber + 1
} else {
n as BlockNumber
}
blocks += 1
};
(next, next + blocks)
}
Blocks::UntilEvent { limit, .. } => (next, next + *limit),
Blocks::JumpBySeconds(secs) => {
let mut blocks = (secs / slot_duration) as BlockNumber;
if secs % slot_duration != 0 {
blocks += 1
};
(next + blocks.saturating_sub(1), next + blocks)
}
Blocks::UntilEvent { limit, .. } => *limit,
};

dbg!(blocks);

(current + 1)..(current + 1 + blocks)
from..to
}
}

Expand Down Expand Up @@ -162,6 +173,7 @@ mod tests {
struct MockEnv;

const SLOT_DURATION: Seconds = 12;
const EMPTY: [BlockNumber; 0] = [];

fn blocks_from(current: BlockNumber, blocks: Blocks<()>) -> Vec<BlockNumber> {
blocks
Expand All @@ -172,11 +184,21 @@ mod tests {

#[test]
fn by_seconds() {
assert_eq!(blocks_from(0, Blocks::BySeconds(0)), [] as [BlockNumber; 0]);
assert_eq!(blocks_from(0, Blocks::BySeconds(0)), EMPTY);
assert_eq!(blocks_from(0, Blocks::BySeconds(1)), [1]);
assert_eq!(blocks_from(0, Blocks::BySeconds(12)), [1]);
assert_eq!(blocks_from(5, Blocks::BySeconds(0)), [] as [BlockNumber; 0]);
assert_eq!(blocks_from(5, Blocks::BySeconds(0)), EMPTY);
assert_eq!(blocks_from(5, Blocks::BySeconds(12)), [6]);
assert_eq!(blocks_from(5, Blocks::BySeconds(60)), [6, 7, 8, 9, 10]);
}

#[test]
fn by_seconds_fast() {
assert_eq!(blocks_from(0, Blocks::JumpBySeconds(0)), EMPTY);
assert_eq!(blocks_from(0, Blocks::JumpBySeconds(1)), [1]);
assert_eq!(blocks_from(0, Blocks::JumpBySeconds(12)), [1]);
assert_eq!(blocks_from(5, Blocks::JumpBySeconds(0)), EMPTY);
assert_eq!(blocks_from(5, Blocks::JumpBySeconds(12)), [6]);
assert_eq!(blocks_from(5, Blocks::JumpBySeconds(60)), [10]);
}
}
6 changes: 5 additions & 1 deletion runtime/integration-tests/src/generic/envs/fudge_env.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,11 @@ impl<T: Runtime + FudgeSupport> Env<T> for FudgeEnv<T> {
self.handle.parachain().with_state(f).unwrap()
}

fn __priv_build_block(&mut self, _i: BlockNumber) {
fn __priv_build_block(&mut self, i: BlockNumber) {
let current = self.state(|| frame_system::Pallet::<T>::block_number());
if i > current + 1 {
panic!("Jump to future blocks is unsupported in fudge (maybe you've used Blocks::BySecondsFast?)");
}
self.handle.evolve();
}
}
Expand Down

0 comments on commit 83a5095

Please sign in to comment.