referrerpolicy=no-referrer-when-downgrade

pallet_revive/evm/api/
type_id.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//! Ethereum Typed Transaction types
18use super::Byte;
19use codec::{Decode, Encode};
20use paste::paste;
21use rlp::Decodable;
22use scale_info::TypeInfo;
23use serde::{Deserialize, Deserializer, Serialize, Serializer};
24
25/// A macro to generate Transaction type identifiers
26/// See <https://ethereum.org/en/developers/docs/transactions/#typed-transaction-envelope>
27macro_rules! transaction_type {
28	($name:ident, $value:literal) => {
29		#[doc = concat!("Transaction type identifier: ", $value)]
30		#[derive(Clone, Default, Debug, Eq, PartialEq)]
31		pub struct $name;
32
33		// upper case const name
34		paste! {
35			#[doc = concat!("Transaction value for type identifier: ", $value)]
36			pub const [<$name:snake:upper>]: u8 = $value;
37		}
38
39		impl $name {
40			/// Convert to u8
41			pub fn value(&self) -> u8 {
42				$value
43			}
44
45			/// Convert to Byte
46			pub fn as_byte(&self) -> Byte {
47				Byte::from($value)
48			}
49
50			/// Try to convert from Byte
51			pub fn try_from_byte(byte: Byte) -> Result<Self, Byte> {
52				if byte.0 == $value {
53					Ok(Self {})
54				} else {
55					Err(byte)
56				}
57			}
58		}
59
60		impl Decodable for $name {
61			fn decode(rlp: &rlp::Rlp) -> Result<Self, rlp::DecoderError> {
62				let value: u8 = rlp.as_val()?;
63				if value == $value {
64					Ok(Self {})
65				} else {
66					Err(rlp::DecoderError::Custom(concat!("expected ", $value)))
67				}
68			}
69		}
70
71		impl Encode for $name {
72			fn using_encoded<R, F: FnOnce(&[u8]) -> R>(&self, f: F) -> R {
73				f(&[$value])
74			}
75		}
76		impl Decode for $name {
77			fn decode<I: codec::Input>(input: &mut I) -> Result<Self, codec::Error> {
78				if $value == input.read_byte()? {
79					Ok(Self {})
80				} else {
81					Err(codec::Error::from(concat!("expected ", $value)))
82				}
83			}
84		}
85
86		impl TypeInfo for $name {
87			type Identity = u8;
88			fn type_info() -> scale_info::Type {
89				<u8 as TypeInfo>::type_info()
90			}
91		}
92
93		impl Serialize for $name {
94			fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
95			where
96				S: Serializer,
97			{
98				serializer.serialize_str(concat!("0x", $value))
99			}
100		}
101		impl<'de> Deserialize<'de> for $name {
102			fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
103			where
104				D: Deserializer<'de>,
105			{
106				let s: &str = Deserialize::deserialize(deserializer)?;
107				if s == concat!("0x", $value) {
108					Ok($name {})
109				} else {
110					Err(serde::de::Error::custom(concat!("expected ", $value)))
111				}
112			}
113		}
114	};
115}
116
117transaction_type!(TypeLegacy, 0);
118transaction_type!(TypeEip2930, 1);
119transaction_type!(TypeEip1559, 2);
120transaction_type!(TypeEip4844, 3);
121transaction_type!(TypeEip7702, 4);
122
123#[test]
124fn transaction_type() {
125	assert_eq!(TYPE_EIP2930, 1u8);
126}