Skip to main content

topsoil_core/system/extensions/
check_genesis.rs

1// This file is part of Soil.
2
3// Copyright (C) Soil contributors.
4// Copyright (C) Parity Technologies (UK) Ltd.
5// SPDX-License-Identifier: Apache-2.0 OR GPL-3.0-or-later WITH Classpath-exception-2.0
6
7use crate::system::{pallet_prelude::BlockNumberFor, Config, Pallet};
8use codec::{Decode, DecodeWithMemTracking, Encode};
9use scale_info::TypeInfo;
10use subsoil::runtime::{
11	traits::{TransactionExtension, Zero},
12	transaction_validity::TransactionValidityError,
13};
14
15/// Genesis hash check to provide replay protection between different networks.
16///
17/// # Transaction Validity
18///
19/// Note that while a transaction with invalid `genesis_hash` will fail to be decoded,
20/// the extension does not affect any other fields of `TransactionValidity` directly.
21#[derive(Encode, Decode, DecodeWithMemTracking, Clone, Eq, PartialEq, TypeInfo)]
22#[scale_info(skip_type_params(T))]
23pub struct CheckGenesis<T: Config + Send + Sync>(core::marker::PhantomData<T>);
24
25impl<T: Config + Send + Sync> core::fmt::Debug for CheckGenesis<T> {
26	#[cfg(feature = "std")]
27	fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
28		write!(f, "CheckGenesis")
29	}
30
31	#[cfg(not(feature = "std"))]
32	fn fmt(&self, _: &mut core::fmt::Formatter) -> core::fmt::Result {
33		Ok(())
34	}
35}
36
37impl<T: Config + Send + Sync> CheckGenesis<T> {
38	/// Creates new `TransactionExtension` to check genesis hash.
39	pub fn new() -> Self {
40		Self(core::marker::PhantomData)
41	}
42}
43
44impl<T: Config + Send + Sync> TransactionExtension<T::RuntimeCall> for CheckGenesis<T> {
45	const IDENTIFIER: &'static str = "CheckGenesis";
46	type Implicit = T::Hash;
47	fn implicit(&self) -> Result<Self::Implicit, TransactionValidityError> {
48		Ok(<Pallet<T>>::block_hash(BlockNumberFor::<T>::zero()))
49	}
50	type Val = ();
51	type Pre = ();
52	fn weight(&self, _: &T::RuntimeCall) -> subsoil::weights::Weight {
53		// All transactions will always read the hash of the genesis block, so to avoid
54		// charging this multiple times in a block we manually set the proof size to 0.
55		<T::ExtensionsWeightInfo as super::WeightInfo>::check_genesis().set_proof_size(0)
56	}
57	subsoil::impl_tx_ext_default!(T::RuntimeCall; validate prepare);
58}