referrerpolicy=no-referrer-when-downgrade

pallet_revive/evm/
tx_extension.rs

1// This file is part of Substrate.
2
3// Copyright (C) Parity Technologies (UK) Ltd.
4// SPDX-License-Identifier: Apache-2.0
5
6// Licensed under the Apache License, Version 2.0 (the "License");
7// you may not use this file except in compliance with the License.
8// You may obtain a copy of the License at
9//
10// 	http://www.apache.org/licenses/LICENSE-2.0
11//
12// Unless required by applicable law or agreed to in writing, software
13// distributed under the License is distributed on an "AS IS" BASIS,
14// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15// See the License for the specific language governing permissions and
16// limitations under the License.
17
18//! Contains transaction extensions needed for ethereum compatability.
19
20use crate::{CallOf, Config, Origin, OriginFor};
21use codec::{Decode, DecodeWithMemTracking, Encode};
22use frame_support::{
23	DebugNoBound, DefaultNoBound,
24	pallet_prelude::{InvalidTransaction, TransactionSource},
25};
26use scale_info::TypeInfo;
27use sp_runtime::{
28	Weight, impl_tx_ext_default,
29	traits::{DispatchInfoOf, TransactionExtension, ValidateResult},
30};
31
32/// An extension that sets the origin to [`Origin::EthTransaction`] in case it originated from an
33/// eth transaction.
34///
35/// This extension needs to be put behind any other extension that relies on a signed origin.
36#[derive(
37	Encode,
38	Decode,
39	DecodeWithMemTracking,
40	Clone,
41	Eq,
42	PartialEq,
43	DefaultNoBound,
44	TypeInfo,
45	DebugNoBound,
46)]
47#[scale_info(skip_type_params(T))]
48pub struct SetOrigin<T: Config + Send + Sync> {
49	/// Skipped as can only be set by runtime code.
50	#[codec(skip)]
51	is_eth_transaction: bool,
52	_phantom: core::marker::PhantomData<T>,
53}
54
55impl<T: Config + Send + Sync> SetOrigin<T> {
56	/// Create the extension so that it will transform the origin.
57	///
58	/// If the extension is default constructed it will do nothing.
59	pub fn new_from_eth_transaction() -> Self {
60		Self { is_eth_transaction: true, _phantom: Default::default() }
61	}
62}
63
64impl<T> TransactionExtension<CallOf<T>> for SetOrigin<T>
65where
66	T: Config + Send + Sync,
67	OriginFor<T>: From<Origin<T>>,
68{
69	const IDENTIFIER: &'static str = "EthSetOrigin";
70	type Implicit = ();
71	type Pre = ();
72	type Val = ();
73
74	fn weight(&self, _: &CallOf<T>) -> Weight {
75		Default::default()
76	}
77
78	fn validate(
79		&self,
80		origin: OriginFor<T>,
81		_call: &CallOf<T>,
82		_info: &DispatchInfoOf<CallOf<T>>,
83		_len: usize,
84		_self_implicit: Self::Implicit,
85		_inherited_implication: &impl Encode,
86		_source: TransactionSource,
87	) -> ValidateResult<Self::Val, CallOf<T>> {
88		let origin = if self.is_eth_transaction {
89			let signer =
90				frame_system::ensure_signed(origin).map_err(|_| InvalidTransaction::BadProof)?;
91			Origin::EthTransaction(signer).into()
92		} else {
93			origin
94		};
95		Ok((Default::default(), Default::default(), origin))
96	}
97
98	impl_tx_ext_default!(CallOf<T>; prepare);
99}