use cumulus_pallet_parachain_system::{
consensus_hook::UnincludedSegmentCapacity,
relay_state_snapshot::{self, ReadEntryErr},
ConsensusHook, RelayChainStateProof,
};
use frame_support::pallet_prelude::*;
use frame_support::storage::types::{StorageValue, ValueQuery};
use frame_support::traits::{StorageInstance, Time};
pub use moonbeam_core_primitives::well_known_relay_keys;
pub struct RelayTimestamp;
impl Time for RelayTimestamp {
type Moment = u64;
fn now() -> Self::Moment {
RelayTimestampNow::get()
}
}
pub struct ConsensusHookWrapperForRelayTimestamp<Runtime, Inner>(
core::marker::PhantomData<(Runtime, Inner)>,
);
impl<Runtime, Inner> ConsensusHook for ConsensusHookWrapperForRelayTimestamp<Runtime, Inner>
where
Runtime: frame_system::Config,
Inner: ConsensusHook,
{
fn on_state_proof(state_proof: &RelayChainStateProof) -> (Weight, UnincludedSegmentCapacity) {
let relay_timestamp: u64 =
match state_proof.read_entry(well_known_relay_keys::TIMESTAMP_NOW, None) {
Ok(relay_timestamp) => relay_timestamp,
Err(relay_state_snapshot::Error::ReadEntry(ReadEntryErr::Proof)) => {
log::error!("Invalid relay storage proof: fail to read key TIMESTAMP_NOW");
panic!("Invalid realy storage proof: fail to read key TIMESTAMP_NOW");
}
Err(relay_state_snapshot::Error::ReadEntry(ReadEntryErr::Decode)) => {
log::error!("Corrupted relay storage: fail to decode value TIMESTAMP_NOW");
panic!("Corrupted relay storage: fail to decode value TIMESTAMP_NOW");
}
Err(relay_state_snapshot::Error::ReadEntry(ReadEntryErr::Absent)) => {
log::error!("Corrupted relay storage: value TIMESTAMP_NOW is absent!");
panic!("Corrupted relay storage: value TIMESTAMP_NOW is absent!");
}
_ => unreachable!(),
};
let wrapper_weight = <Runtime as frame_system::Config>::DbWeight::get().writes(1);
RelayTimestampNow::put(relay_timestamp);
let (weight, capacity) = Inner::on_state_proof(state_proof);
(weight.saturating_add(wrapper_weight), capacity)
}
}
struct RelayTimestampNowPrefix;
impl StorageInstance for RelayTimestampNowPrefix {
const STORAGE_PREFIX: &'static str = "RelayTimestampNow";
fn pallet_prefix() -> &'static str {
"runtime"
}
}
type RelayTimestampNow = StorageValue<RelayTimestampNowPrefix, u64, ValueQuery>;