partner_chains_mock_data_sources/
block.rs

1use crate::Result;
2use sidechain_domain::*;
3use sp_timestamp::Timestamp;
4
5pub struct BlockDataSourceMock {
6	/// Duration of a mainchain epoch in milliseconds
7	mc_epoch_duration_millis: u32,
8}
9
10impl BlockDataSourceMock {
11	pub async fn get_latest_block_info(&self) -> Result<MainchainBlock> {
12		Ok(self
13			.get_latest_stable_block_for(Timestamp::new(BlockDataSourceMock::millis_now()))
14			.await
15			.unwrap()
16			.unwrap())
17	}
18
19	pub async fn get_latest_stable_block_for(
20		&self,
21		reference_timestamp: Timestamp,
22	) -> Result<Option<MainchainBlock>> {
23		let block_number = (reference_timestamp.as_millis() / 20000) as u32;
24		let epoch = block_number / self.block_per_epoch();
25		let mut hash_arr = [0u8; 32];
26		hash_arr[..4].copy_from_slice(&block_number.to_be_bytes());
27		Ok(Some(MainchainBlock {
28			number: McBlockNumber(block_number),
29			hash: McBlockHash(hash_arr),
30			epoch: McEpochNumber(epoch),
31			slot: McSlotNumber(block_number as u64),
32			timestamp: reference_timestamp.as_millis(),
33		}))
34	}
35
36	pub async fn get_stable_block_for(
37		&self,
38		_hash: McBlockHash,
39		reference_timestamp: Timestamp,
40	) -> Result<Option<MainchainBlock>> {
41		self.get_latest_stable_block_for(reference_timestamp).await
42	}
43
44	pub async fn get_block_by_hash(&self, hash: McBlockHash) -> Result<Option<MainchainBlock>> {
45		// reverse of computation in `get_latest_stable_block_for`
46		let block_number = u32::from_be_bytes(hash.0[..4].try_into().unwrap());
47		let timestamp = block_number * 20000;
48		let epoch = block_number / self.block_per_epoch();
49		Ok(Some(MainchainBlock {
50			number: McBlockNumber(block_number),
51			hash,
52			epoch: McEpochNumber(epoch),
53			slot: McSlotNumber(epoch.into()),
54			timestamp: timestamp.into(),
55		}))
56	}
57}
58
59impl BlockDataSourceMock {
60	pub fn new(mc_epoch_duration_millis: u32) -> Self {
61		Self { mc_epoch_duration_millis }
62	}
63
64	pub fn new_from_env() -> Result<Self> {
65		let mc_epoch_duration_millis: u32 =
66			std::env::var("MC__EPOCH_DURATION_MILLIS")?.parse::<u32>()?;
67		Ok(Self::new(mc_epoch_duration_millis))
68	}
69
70	fn block_per_epoch(&self) -> u32 {
71		self.mc_epoch_duration_millis / 20000
72	}
73
74	fn millis_now() -> u64 {
75		std::time::SystemTime::now()
76			.duration_since(std::time::UNIX_EPOCH)
77			.unwrap()
78			.as_millis() as u64
79	}
80}